convert string to a method of a class at runtime?

Kevin Altis altis at semi-retired.com
Sun Jun 2 17:20:25 EDT 2002


I would like to be able to take a string containing the definition of a
method, compile the method and then add it to an instance variable at
runtime, so that the method defined in the string is part of the class just
as if it had actually been in the class definition to begin with when the
module was first used. So, instead of a class definition like:

class H:
    def hello(self, s):
        print s

   def world(self, s):
        print s

I would like to have just the 'hello' method defined beforehand and add
'world' at runtime.

Here's a shell transcript of my attempt to add the 'world' method by
compiling it and using the 'new' module to turn the compiled string into a
method of the class. As the transcript shows, my attempt failed, so I'm
hoping some Python language experts will be able to tell me what steps I got
wrong. Perhaps, I need to use a different method to define the argument list
or change where the global namespace comes from; I thought the namespace
should be the same as that already defined for the instance or class?

>>> class H:
...     def hello(self, s):
...         print s
...
>>> h = H()
>>> h.hello('world')
world
>>> s = """def world(self, s):
...     print s
...
... """
>>> s
'def world(self, s):\n    print s\n\n'
>>> c = compile(s, '', 'exec')
>>> c
<code object ? at 0164B620, file "", line 1>
>>> import new
>>> f = new.function(c, globals())
>>> h.__class__.__dict__['world'] = new.instancemethod(f, None, h.__class__)
>>> h.world('new world')
Traceback (most recent call last):
  File "<input>", line 1, in ?
TypeError: ?() takes no arguments (2 given)
>>>

Fingers crossed, that this kind of dynamic method addition is doable. I know
I can do it by just typing a function into the shell like this:

>>> def world2(self, s):
...     print s
...
>>> f2 = new.instancemethod(world2, None, h.__class__)
>>> f2
<unbound method H.world2>
>>> h.__class__.__dict__['world2'] = f2
>>> h.world2('yea')
yea

But I need to be able to do the addition outside the shell, so compiling the
string is necessary. In more complex examples, the method needs the
namespace to be right so it can make use of whatever imports and other
global variables have been setup.

Thanks,

ka
---
Kevin Altis
altis at semi-retired.com





More information about the Python-list mailing list