modifying __class__

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Sun Oct 28 13:14:28 EDT 2007


En Fri, 26 Oct 2007 04:49:37 -0300, Evan Klitzke <evan at yelp.com> escribi�:

> On 10/26/07, Piyush Jain <piyush.subscription at gmail.com> wrote:
>> Hi,
>> Itis possible to change the class of an object by assigning new value to
>> __class__
>> Is it possible to call my module when it is done.
>> For example,
>> object = ClassA()
>>
>> object.__class__ = classB # I want to call my method when this  
>> statement is
>> executed.
>
> Here's an example of how to do this:
>
> class A(object):
>         def __init__(self):
>                 self._class = A
>
>         def getclass(self):
>                 return self._class
>
>         def setclass(self, x):
>                 print 'setting __class__ to %s' % x
>                 self._class = x
>
>         __class__ = property(getclass, setclass)
>
> class B(object):
>         pass
>
> if __name__ == '__main__':
>         a = A()
>         print 'Running a.__class__ = B'
>         a.__class__ = B
>
>         print 'a.__class__ = %s' % a.__class__

Sorry but this is unnecesarily complicated and almost useless. Ok, using a  
property you change the __class__ attribute, but this has no effect on the  
object behavior. type(a) is still A, and B is not overriding any of A  
methods.

>> I want to do it in a general way. For ex. , whenever __class__ is  
>> changed
>> for any object instance (of different classes), my own function is  
>> called.
>> How should I do it ?
> I think you can do this using a metaclass, and then have all of your
> classes inherit from the metaclass rather than object, but I don't
> really have any experience doing this.

Perhaps, but using a metaclass is still too much complicated for this task.
I assume the OP doesn't have a lot of __class__ assignments all along the  
code, so keeping the syntax x.__class__ = another_class is not a  
requirement.
So, just define a function change_class wich assigns the new class to  
__class__ and additionally does whatever is needed:

py> class A(object):
...     def foo(self):
...         print "Inside A.foo"
...
py> class B(object):
...     def foo(self):
...         print "Inside B.foo"
...
py> def change_class(inst, newclass):
...     print "Look ma! Changing class from %s to %s" % (
...              inst.__class__, newclass)
...     inst.__class__ = newclass
...
py> x = A()
py> x.foo()
Inside A.foo
py> type(x)
<class '__main__.A'>
py> change_class(x, B)
Look ma! Changing class from <class '__main__.A'> to <class
'__main__.B'>
py> x.foo()
Inside B.foo
py> type(x)
<class '__main__.B'>

change_class might be a method of A instead, but I don't see any gain on  
it.

-- 
Gabriel Genellina




More information about the Python-list mailing list