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