some simple functions for dynamically adding methods, properties,and classmethods to classes at runtime
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | #!/usr/bin/env python
#-----------------------------------------------------------------------------
#   Copyright 2003 by Bud P. Bruegger, Sistema, Italy
#   mailto:bud@sistema.it
#   http://www.sistema.it
#-----------------------------------------------------------------------------
#   dynClass -- Dynamic Classes
#   ---------------------------
#   
#   some simple functions for dynamically adding methods, properties
#   and classmethods to classes at runtime.  
#   
#-----------------------------------------------------------------------------
# see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81732 
# and http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81982
# and http://www.python.org/2.2/descrintro.html#property
import new
import sys
def addMethod(classInstance, func, methName=None):
    """adds function as a new method to an existing class
       function should have self as first argument
    """
    meth = new.instancemethod(func, None, classInstance)
    name = methName or func.__name__
    setattr(classInstance, name, meth)
    return name
def addProperty(classInstance, attrName, fget, fset, fdel=None, \
              fdoc="this is magic"):
    """adds a property to an existing class """
    prop = property(fget, fset, fdel, fdoc)
    setattr(classInstance, attrName, prop)
def addClassMethod(classInstance, func, methName=None):
    """adds function as a new class method to an existing class.
       function should have self as first argument
    """
    name = methName or func.__name__
    setattr(classInstance, name, classmethod(func))
def classFromName(className):
    "returns the class instance object"
    return getattr(sys.modules['__main__'], className)
#==========  example usage ====================================================
if __name__ == "__main__":
    pass 
    #-- testing addMethod ------------------
    def func1(self):
        "some test function"
        return "Name is %s" % self._name
    
    def func2(self, comment=''):
        "some test function"
        return "Age is %s %s" % (self._age, comment)
    
    class Example(object):
        "some example class"
    
        def __init__(self, name, age):
            self._name = name
            self._age = age
    
    sarah = Example('Sarah', 5)
    josh = Example('Josh', 2)
    
    addMethod(Example, func1, 'getName')
    addMethod(Example, func2, 'getAge')
    
    lucia = Example('Lucia', 20)
    
    # Does it work as expected?
    
    print sarah.getName()
    print sarah.getAge('at least soon')
    print josh.getName()
    print josh.getAge('and wild')
    print lucia.getName()
    print lucia.getAge('some time ago')
    print "\n-----------------------\n"
    
    
    #-- testing properties ------------------
    
    def getAltName(self):
        return "*" + self._name + "*"
    
    def setAltName(self, val):
        self._name = val[1:-1]
    
    addProperty(Example, 'altName', getAltName, setAltName)
    print sarah.altName
    sarah.altName="*NEW-SARAH*"
    print sarah.altName
    print sarah.getName()
    bud = Example('Bud', 42)
    print bud.altName
    bud.altName="*The king of beers*"
    print bud.altName
    print bud.getName()
    print "\n-----------------------\n"
    
    #-- testing classFromName -----------
    print "The class named 'Example' is %s" % classFromName('Example')
    class EEE(object):
        pass
    print "The class named 'EEE' is %s" % classFromName('EEE')
    print "\n-----------------------\n"
    
    #-- testing addClassMethod -----------------------
    class C(object):
        pass
    def func(cls):
        return "<<%s>>" % cls.__name__
    addClassMethod(C, func, 'className')
    print "the class name is: ", C.className()
 | 
It is sometimes useful to modify classes at runtime, for example to implement some weakly coupled persistance mechanism for user-defined classes. While some recipes already address related issues (see links in code), this submission attempts to consolidate them in a single reusable module.

 Download
Download Copy to clipboard
Copy to clipboard