How to code dynamically created methods?

K

kj

I've tried a bazillion ways to code dynamically generated methods,
to no avail.

The following snippet is a very simplified (and artificial) demo
of the problem I'm running into, featuring my latest attempt at
this. The idea here is to use __getattr__ to trap any attempt to
invoke a nonexistent method, have it return a generic handler called
_auto which creates the new method dynamically, invokes it, and
"installs" it in the class, so that subsequent calls to the same
method go directly to the newly created method, instead of to
__getattr__. It is this last step, the "installation" of the new
method, that is giving me problems.


class A( object ):
def __getattr__( self, name ):
self._auto_name = name
return self._auto

def hello( self, name ):
print "hi! my name is %s" % name

def _auto( self, *args ):
name = self._auto_name
def m( self, *args ): self.hello( name )
m( self, *args )

m = classmethod( m )
setattr( A, name, m )

x = A()
x.foo() # ok
x.foo() # bombs

last):
File "<stdin>", line 1, in ? File "test.py", line 19, in ?
x.foo() File "test.py", line 12, in m
self.hello( name ) TypeError: unbound method hello() must be
called with A instance as first argument (got str instance instead)
I'm sure that the problem is with my naive attempt to add a method
to class A dynamically (in the last two lines of the definition of
_auto). What's the right way to do this?

Thanks!

kj
 
K

kj

Nevermind, I found the problem...

Thanks,

kj



I've tried a bazillion ways to code dynamically generated methods,
to no avail.
The following snippet is a very simplified (and artificial) demo
of the problem I'm running into, featuring my latest attempt at
this. The idea here is to use __getattr__ to trap any attempt to
invoke a nonexistent method, have it return a generic handler called
_auto which creates the new method dynamically, invokes it, and
"installs" it in the class, so that subsequent calls to the same
method go directly to the newly created method, instead of to
__getattr__. It is this last step, the "installation" of the new
method, that is giving me problems.

class A( object ):
def __getattr__( self, name ):
self._auto_name = name
return self._auto
def hello( self, name ):
print "hi! my name is %s" % name

def _auto( self, *args ):
name = self._auto_name
def m( self, *args ): self.hello( name )
m( self, *args )
m = classmethod( m )
setattr( A, name, m )
 
J

Jay Loden

kj said:
I've tried a bazillion ways to code dynamically generated methods,
to no avail.

The following snippet is a very simplified (and artificial) demo
of the problem I'm running into, featuring my latest attempt at
this. The idea here is to use __getattr__ to trap any attempt to
invoke a nonexistent method, have it return a generic handler called
_auto which creates the new method dynamically, invokes it, and
"installs" it in the class, so that subsequent calls to the same
method go directly to the newly created method, instead of to
__getattr__. It is this last step, the "installation" of the new
method, that is giving me problems.


class A( object ):
def __getattr__( self, name ):
self._auto_name = name
return self._auto

def hello( self, name ):
print "hi! my name is %s" % name

def _auto( self, *args ):
name = self._auto_name
def m( self, *args ): self.hello( name )
m( self, *args )

m = classmethod( m )
setattr( A, name, m )

x = A()
x.foo() # ok
x.foo() # bombs

I tried to do the same exact thing recently and got my answer from the mailing list. Here's the test code I got working using the help from the list:

#!/usr/bin/python

import functools

class TestClass:
def __init__(self):
pass

def __getattr__(self, name):
try:
return getattr(self.__class__, name)
except AttributeError:
return functools.partial(self.foo, name)

def foo(self, name, **args):
print name
for i in args:
print " %s=%s" % (i, args)

def bar(self):
print "bar()"

test = TestClass()
test.someMethod()
test.anotherMethod()
test.someMethod()
test.bar()

Hope that helps,

-Jay
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top