On Mon, 19 Feb 2007 23:18:02 -0800, Ziga Seilnacht wrote: > George Sakkis wrote: >> I was kinda surprised that setting __class__ or __dict__ goes through >> the __setattr__ mechanism, like a normal attribute: >> >> class Foo(object): >> def __setattr__(self, attr, value): >> pass >> >> class Bar(object): >> pass >> >> >>> f = Foo() >> >>> f.__class__ = Bar >> >>> print f.__class__ is Foo >> True >> >> Is there a way (even hackish) to bypass this, or at least achieve >> somehow the same goal (change f's class) ? >> >> George > >>>> object.__setattr__(f, '__class__', Bar) >>>> f.__class__ is Bar > True
This version is arguably more "correct", although a tad longer to write, and doesn't need you to hard-code the class superclass: super(f.__class__, f).__setattr__('__class__', Bar) But what surprised me was that this *didn't* work: >>> f = Foo() >>> f.__dict__['__class__'] = Bar >>> f.__class__ <class '__main__.Foo'> Unless I'm confused, it looks like instance.__class__ bypasses the usual lookup mechanism (instance.__dict__, then instance.__class__.__dict__) for some reason. >>> Foo.x = 1 # stored in class __dict__ >>> f.x 1 >>> f.__dict__['x'] = 2 # stored in instance __dict__ >>> f.x 2 >>> Foo.x 1 But __class__ doesn't behave like this. Why? -- Steven. -- http://mail.python.org/mailman/listinfo/python-list