Add methods to a class dynamically

Duncan Booth duncan at NOSPAMrcp.co.uk
Fri Jun 6 10:52:10 EDT 2003


tr at jotsite.com (Hoang Do) wrote in
news:64fb4467.0306060628.2c51bf09 at posting.google.com: 

> I am having trouble invoking the created method.  The function
> addition goes fine but invoking it gives an error.  Here is some
> simple code: ---------------------------------------------------------
> class DynObj:
>     def __init__(self):
>         self.methods = ("a", "b", "c")
>         for method in self.methods:
>            self. __generateMethod(method)
>     def __generateMethod(self, methodName):
>         code = "def %s(self):\n\tprint %s\n" % (methodName, methodName)
Try this instead:
          code = "def %s(self):\n\tprint self.%s\n" % (methodName, methodName)

>         exec code in globals(), self.__dict__
> 
> if __name__ == "__main__":
>     x = DynObj()
>     print dir(x)
>     x.a(x)
> ---------------------------------------------------------
> The Error:
> NameError: global name 'a' is not defined
> ---------------------------------------------------------
> Methods "a", "b", and "c" are callable and in DynObj's __dict__. 
> However, I can't seem to call it.
> 
> Calling for help from anyone familiar with Python's introspective
> features? 
> 
Your problem is mainly trying to access the global function 'a'
from the print statement. Fix it as shown above.

The other problem is that you put a function into the instance so
you have to explicitly pass the self parameter when calling it. You
probably want to create a bound method instead:

    def __generateMethod(self, methodName):
        d = {}
        code = "def %s(self):\n\tprint self.%s\n" % (methodName, methodName)
        exec code in globals(), d
        setattr(self, methodName, d[methodName].__get__(self, self.__class__))

...
>>> x.a()
<bound method DynObj.a of <__main__.DynObj instance at 0x0096CF20>>



-- 
Duncan Booth                                             duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?




More information about the Python-list mailing list