run time code generation in python

Discussion in 'Python' started by Carlo v. Dango, Oct 9, 2003.

  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 have tried the compile(str)
    method but I haven't succeeded. I've tried using the __getattribute__ but
    there is a problem in that I do not know if __getattribute__ was called due
    to a method call taking place, or due to someone who just wants a reference
    to a method.. (and for other reasons as well :) I need to runtime generate
    the above method.

    hope some one has some good pointers to run time code generation in
    python..

    many thanks

    Carlo Van Dango
    Carlo v. Dango, Oct 9, 2003
    #1
    1. Advertising

  2. Carlo v. Dango

    Duncan Booth Guest

    "Carlo v. Dango" <> wrote in
    news:Xns940F929A63B436020206@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:

    def forwarder(obj, name):
    def fwd(*args, **kwargs):
    getattr(obj.i, name)(*args, **kwargs)
    return fwd

    something.foo = forwarder(something, 'foo')
    something.foo(42) # Calls something.i.foo(42)

    Alternatively:

    def forwarder(obj, name):
    def fwd(*args, **kwargs):
    getattr(obj, name)(*args, **kwargs)
    return fwd

    something.foo = forwarder(something.i, 'foo')
    something.foo(42) # Calls something.i.foo(42)

    (I'm assuming you want a bit more in the function definition, otherwise of
    course, 'something.foo=something.i.foo' is an even easier solution).

    All code samples above are untested and therefore almost certainly wrong.

    --
    Duncan Booth
    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?
    Duncan Booth, Oct 9, 2003
    #2
    1. Advertising

  3. Duncan Booth <> wrote in
    news:Xns940F8FDA1866Cduncanrcpcouk@127.0.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)



    because there potentially could be many forwarder methods applied the
    instance (forwarding to different methods.. but ofcourse are named
    differently themselves)... hence it would not know where to find its
    name.. hmm.. maybe if the method could somehow find out its own name, it
    would know what to call on the i attribute. Is that possible?


    > 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


    aahh.. ok so i can only store functions and not methods! nice point! hmm
    but in this particular case I'm taking over the handling of self anyway
    so it will not hurt me I think.. except that I have to get hold of the
    attribute i on the instance. So that's why you use getattr() rather than
    self.i


    > 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:


    well I need to insert it in the instance.. but yes I thought about
    inserting the function in the class.. I thought I may be able to insert
    the function during the __init__ execution..

    >
    > (I'm assuming you want a bit more in the function definition,
    > otherwise of course, 'something.foo=something.i.foo' is an even easier
    > solution).


    well, outsiders may not know that there is a forwarding taking place..
    and I need only this since I have wrapper methods on top of each method
    execution.. or atleast Ive made that using metaclasses.. but this is not
    enough as I've found out I need to operate purely on an instance level..


    > All code samples above are untested and therefore almost certainly
    > wrong.


    no problem. ;-)


    -Carlo
    Carlo v. Dango, Oct 9, 2003
    #3
  4. Carlo v. Dango

    Duncan Booth Guest

    "Carlo v. Dango" <> wrote in
    news:Xns940F9DEEABCA26020206@172.16.0.1:

    >> 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)

    >
    >
    > because there potentially could be many forwarder methods applied the
    > instance (forwarding to different methods.. but ofcourse are named
    > differently themselves)... hence it would not know where to find its
    > name.. hmm.. maybe if the method could somehow find out its own name, it
    > would know what to call on the i attribute. Is that possible?


    That's why my other examples all generated the wrapper function inside
    another function. That way you use the nested scope variables to store
    useful things like the attribute name.

    --
    Duncan Booth
    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?
    Duncan Booth, Oct 9, 2003
    #4
  5. Carlo v. Dango

    Terry Reedy Guest

    "Carlo v. Dango" <> wrote in message
    news:Xns940F929A63B436020206@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 have tried the

    compile(str)
    > method but I haven't succeeded.


    compile() gives you a code object;
    you probably want 'exec string' to get a function in the current
    namespace

    >>> exec "def g(): print 'g defined' "
    >>> g()

    g defined

    or follow other responder's advice...

    Terry J. Reedy
    Terry Reedy, Oct 9, 2003
    #5
  6. On Thu, 9 Oct 2003 13:12:10 +0000 (UTC), Duncan Booth <> wrote:

    >"Carlo v. Dango" <> wrote in
    >news:Xns940F929A63B436020206@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.

    >>> class Foo(object):

    ... def __init__(self, name): self.name=name
    ... def foometh(self, other):
    ... print 'foometh bound to self named %r' %self.name
    ... print 'name of other instance: %r'% other.name
    ...
    >>> foo = Foo('alice')
    >>> bar = Foo('bob')
    >>> foo.foometh(bar)

    foometh bound to self named 'alice'
    name of other instance: 'bob'
    >>> bar.foometh(foo)

    foometh bound to self named 'bob'
    name of other instance: 'alice'
    >>> foo.bar = bar.foometh
    >>> bar.foo = foo.foometh
    >>> foo.bar(foo)


    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).


    >def forwarder(obj, name):
    > def fwd(*args, **kwargs):
    > getattr(obj.i, name)(*args, **kwargs)
    > return fwd
    >
    >something.foo = forwarder(something, 'foo')
    >something.foo(42) # Calls something.i.foo(42)
    >
    >Alternatively:
    >
    >def forwarder(obj, name):
    > def fwd(*args, **kwargs):
    > getattr(obj, name)(*args, **kwargs)
    > return fwd
    >
    >something.foo = forwarder(something.i, 'foo')
    >something.foo(42) # Calls something.i.foo(42)
    >
    >(I'm assuming you want a bit more in the function definition, otherwise of
    >course, 'something.foo=something.i.foo' is an even easier solution).
    >

    I was wondering about that too. The larger picture is still unclear to me ;-)

    Regards,
    Bengt Richter
    Bengt Richter, Oct 12, 2003
    #6
  7. On 12 Oct 2003 11:41:34 GMT, (Bengt Richter) wrote:

    >On Thu, 9 Oct 2003 13:12:10 +0000 (UTC), Duncan Booth <> wrote:
    >
    >>"Carlo v. Dango" <> wrote in
    >>news:Xns940F929A63B436020206@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
    Bengt Richter, Oct 12, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ian Bicking

    Re: run time code generation in python

    Ian Bicking, Oct 9, 2003, in forum: Python
    Replies:
    1
    Views:
    427
    Carlo v. Dango
    Oct 9, 2003
  2. Robert Brewer

    RE: run time code generation in python

    Robert Brewer, Oct 9, 2003, in forum: Python
    Replies:
    1
    Views:
    333
    Carlo v. Dango
    Oct 16, 2003
  3. flamesrock
    Replies:
    8
    Views:
    440
    Hendrik van Rooyen
    Nov 24, 2006
  4. Pierre Yves
    Replies:
    2
    Views:
    475
    Pierre Yves
    Jan 10, 2008
  5. John W. Long

    HTML Generation (Next Generation CGI)

    John W. Long, Nov 22, 2003, in forum: Ruby
    Replies:
    4
    Views:
    319
    John W. Long
    Nov 24, 2003
Loading...

Share This Page