Dynamic subclassing ?

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Sun Jun 10 19:32:44 EDT 2007


En Sun, 10 Jun 2007 18:16:12 -0300, James T. Dennis <jadestar at idiom.com>  
escribió:

>  When I try something like this I run into a little problem:
>
> 	class Foo:
> 	    def foo(self):
> 	        return "foo"
> 	class Bar:
> 	    def bar(self):
> 	        return "bar"
>
> 	f = Foo()
> 	f.__dict__.update(Bar.__dict__)
>
>  ... the problem is that while f now has a "bar" method it doesn't
>  work quite like a normal instance method:
>
> 	>>> f.bar()
> 	Traceback (most recent call last):
> 	  File "<stdin>", line 1, in ?
> 	TypeError: bar() takes exactly 1 argument (0 given)
> 	>>>
>
>  ... though I can get by with f.bar(f)

Bar.__dict__ contains *unbound* methods - that is, methods not linked to  
any particular instance. If you copy them directly into f.__dict__ you  
lose the "magic" that binds methods to instances.
You could store a bound method into the instance but it's not a good idea  
(there are cyclic references).
I think the easiest way is to define a dynamic class (as the subject on  
this old thread suggests):

py> f = Foo()
py> Foo2 = type("Foo2", (Foo,Bar), {})
py> f.__class__ = Foo2
py> f.bar()
'bar'

The code above changes the object class once it was created, but you don't  
have to. Also, you don't have to use a different class name (altough it  
may be confusing...):

py> f = type("Foo", (Foo,Bar), {})()
py> f.bar()
'bar'

>  This "new" module seems to be the key to it all;

It's almost useless now that types are callable.

> but the only docs I have for that say:
>
>>>> help(new)
> Help on module new:
> [...]
> MODULE DOCS
>     http://www.python.org/doc/current/lib/module-new.html

Did you follow the above link?

-- 
Gabriel Genellina




More information about the Python-list mailing list