Add methods to a class at runtime?

holger krekel pyth at devel.trillke.net
Sun Sep 1 19:10:14 EDT 2002


Gerhard H?ring wrote:
> * Robert Oschler <Oschler at earthlink.net> [2002-09-01 17:19 -0400]:
> > Ok bear with me guys (Gerhard and Peter).  I'm not lazy, the reason I
> > don't test certain things I should is because Python is capable of
> > such amazing introspective dynamism that, having a _very_ long
> > experience bank in strongly typed "static" languages like C++ and
> > Pascal, I find I don't even consider yet even trying certain
> > possibilies that Python is capable of.
> > Some interesting tidbits I found while trying out your suggestions, as
> > you will see in the two ".py" files that follow, I discovered that to
> > create a method you can dynamically add to a class _instance_, you
> > need to omit the 'self' parameter in the method declaration.
> 
> Yep, I found that out today too, when I wrote my last reply. Though I've
> never used that in real life.
> 
> > [...] I'm running 2.1.1, anybody know if 2.2.2 is going "disable"
> > either of these abilities?
> 
> It will be strictly (even binary) compatible with Python 2.2.{0|1}, so
> the answer is that these features will stay.

Even with future version you should be able to rely on this. 
Attribute names are first looked up in the instance and if they are bound 
to a function object you can call it. 

> >>> class Foo:
> ...   def action(self): print "foo"
> ... 
> >>> class Bar:
> ...   def action(self): print "bar"
> ... 
> >>> foo = Foo()
> >>> foo.__class__
> <class __main__.Foo at 0x80d39ac>
> >>> foo.action()
> foo
> >>> foo.__class__ = Bar
> >>> foo.action()
> bar
> >>> foo.__class__
> <class __main__.Bar at 0x80e75c4>
> >>> 
> 
> AFAIK Guido isn't too fond of this feature. I guess it might go away
> some day.

With new-style classes (python 2.2) it's already somewhat restricted:

>>> class a(object):
        pass

>>> class b(dict):
        pass

>>> a1=a()
>>> a1.__class__=b
------------------------------------------------------------
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: __class__ assignment: 'b' object layout differs from 'a'
>>>

regards,

    holger




More information about the Python-list mailing list