Adding method to a class on the fly
James Stroud
jstroud at mbi.ucla.edu
Fri Jun 22 21:55:08 EDT 2007
John Henry wrote:
> Hi list,
>
> I have a need to create class methods on the fly. For example, if I
> do:
>
> class Dummy:
> def __init__(self):
> exec '''def method_dynamic(self):\n\treturn
> self.method_static("it's me")'''
> return
>
> def method_static(self, text):
> print text
> return
Where is the text for the exec statement coming from? A file? User
input? What you are doing above makes absolutely no sense. You confuse
everyone who attempts to understand what you want to do with the above
because no one in his right mind would do anything like it.
> I like that to be the same as:
>
> class Dummy:
> def __init__(self):
> return
>
> def method_dynamic(self):
> return self.method_static("it's me")
>
> def method_static(self, text):
> print text
> return
Are you looking to fill in text and create new methods for Dummy based
on the text and method_static() such that these will become true
instance methods for instances of Dummy?
def add_dynamic(cls_name, f, name, *args, **kwargs):
cls = globals()[cls_name]
def _f(self):
return getattr(cls, f)(self, *args, **kwargs)
setattr(cls, name, _f)
e.g.
py> class Dummy:
... def method_static(self, text):
... print text
... return
...
py> def add_dynamic(cls_name, f, name, *args, **kwargs):
... cls = globals()[cls_name]
... def _f(self):
... return getattr(cls, f)(self, *args, **kwargs)
... setattr(cls, name, _f)
...
py> add_dynamic('Dummy', 'method_static', 'method_dynamic', 'abc xyz')
py> Dummy.method_dynamic
<unbound method Dummy._f>
py> d = Dummy()
py> d.method_dynamic()
abc xyz
Note that this is "completely dynamic" in that all arguments to
add_dynamic() are strings. This may or may not be what you want--in such
a case, you will want to study the code to see how it works and fix it
yourself. Note also that methods added to classes after instances are
made will be available to said instances:
py> add_dynamic('Dummy', 'method_static', 'method2_dynamic', 'asdf jkl')
py> d.method2_dynamic()
asdf jkl
> so that I can do:
>
> dum=Dummy.method_dynamic()
Here you confuse everyone. This last line is not the same as you
describe in the above example. Here you imply the dynamic creation of a
"static method" (not a "method_static"--don't be confused by the names
you invent as they may already have a meaning to everyone else). Static
methods are different from unbound class methods that are later bound to
instances of a class upon instantiation.
Here is an analagous solution for static methods:
def add_static(cls_name, f, name, *args, **kwargs):
cls = globals()[cls_name]
def _f():
return getattr(cls, f)(*args, **kwargs)
setattr(cls, name, staticmethod(_f))
class Dummy:
@staticmethod
def method_static(text):
print text
e.g.:
py> def add_static(cls_name, f, name, *args, **kwargs):
... cls = globals()[cls_name]
... def _f():
... return getattr(cls, f)(*args, **kwargs)
... setattr(cls, name, staticmethod(_f))
...
py> class Dummy:
... @staticmethod
... def method_static(text):
... print text
...
py> add_static('Dummy', 'method_static', 'real_static', 'aaa bbb')
py> Dummy.real_static
<function _f at 0x406bf684>
py> Dummy.real_static()
aaa bbb
Again, this will do what you want, but if it doesn't do *exactly* what
you want, you need to study and modify the code. Also, creating static
methods from unbound methods requires trickery. If this is what you
want, you should be very clear about it.
> and see "it's me" printed.
>
> Can that be done?
Yes. Anything is possible with python. That's why I use it.
James
More information about the Python-list
mailing list