run time code generation in python

Bengt Richter bokr at oz.net
Sun Oct 12 08:56:26 EDT 2003


On 12 Oct 2003 11:41:34 GMT, bokr at oz.net (Bengt Richter) wrote:

>On Thu, 9 Oct 2003 13:12:10 +0000 (UTC), Duncan Booth <duncan at NOSPAMrcp.co.uk> wrote:
>
>>"Carlo v. Dango" <amigo at fake.not> wrote in
>>news:Xns940F929A63B436020206 at 172.16.0.1: 
>>
>>> 
>>> Hello there. I have found a need to runtime generate a method and
>>> instert it into an object instance. The code is a simple forwarding
>>> mechanism like 
>>> 
>>> def foo(self, *args, **kwargs):
>>>     self.i.foo(*args, **kwargs)
>>> 
>>> method.. however, it is only at runtime that I know the name "foo" so
>>> I cannot gerenate such a method any sooner. 
>>
>>I don't see why you need to generate any code at runtime.
>>This does the same as your code, only now the name of the function to which 
>>you are forwarding the call is stored in a variable:
>>
>>name = 'foo'
>>def foo(self, *args, **kwargs):
>>    getattr(self.i, name)(*args, **kwargs)
>>
>>You should be aware that if you store a function in an instance at runtime, 
>>the magic binding to 'self' won't happen. You either need to store the 
>>function in the class, or leave out the self parameter if you want to 
>>insert it into an instance. Something like this may be what you need:
>>
>I don't quite understand the background motivation, but you can store
>bound methods as attributes of arbitrary instances. They can happen to
>be bound to the same instance or not (see switcheroos below):
>Note that they can shadow methods of the same name, do deleting reveals
>the class-defined methods.
>
[... pasting-problem, sorry :-/ ]

 >>> class Who(object):
 ...     def __init__(self, name): self.name = name
 ...     def speak(self): return 'My name is %r'%self.name
 ...
 >>> alice = Who('Alice')
 >>> bob = Who('Bob')
 >>>
 >>> alice.speak(), bob.speak()
 ("My name is 'Alice'", "My name is 'Bob'")
 >>> alice.speak, bob.speak = bob.speak, alice.speak
 >>> alice.speak(), bob.speak()
 ("My name is 'Bob'", "My name is 'Alice'")
 >>> del alice.speak
 >>> alice.speak(), bob.speak()
 ("My name is 'Alice'", "My name is 'Alice'")
 >>> del bob.speak
 >>> alice.speak(), bob.speak()
 ("My name is 'Alice'", "My name is 'Bob'")
 >>>

>You can get to the unbound method via the instance's class, and re bind it
>
> >>> alice.__class__.speak
> <unbound method Who.speak>
> >>> alice.__class__.speak(bob)
> "My name is 'Bob'"
> >>> alice.__class__.speak(alice)
> "My name is 'Alice'"
> >>> bound_bob = alice.__class__.speak.__get__(bob)
> >>> bound_bob()
> "My name is 'Bob'"
> >>> bound_alice = alice.__class__.speak.__get__(alice)
> >>> bound_alice()
> "My name is 'Alice'"
> >>> bob.alice = bound_alice
> >>> bob.alice()
> "My name is 'Alice'"
> >>> bob.bob = bound_bob
> >>> bob.bob()
> "My name is 'Bob'"
> >>> bob.speak()
> "My name is 'Bob'"
>
>(I left the class out of those __get__ calls. Not sure when that will cause a
>problem).
[...]

Regards,
Bengt Richter




More information about the Python-list mailing list