On Feb 20, 12:57 pm, Steven D'Aprano <[EMAIL PROTECTED]> wrote: > 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? >
Magic attributes like __class__ are looked up on the class rather than the instance. Fuzzyman http://www.voidspace.org.uk/python/articles.shtml > -- > Steven. -- http://mail.python.org/mailman/listinfo/python-list