On Mon, Aug 20, 2012 at 12:01 PM, Massimo Di Pierro <massimo.dipie...@gmail.com> wrote: > I discovered I can do this: > > class A(object): pass > class B(object): > __class__ = A # <<<< magic > > b = B() > isinstance(b,A) # returns True (as if B derived from A) > isinstance(b,B) # also returns True > > I have some reasons I may want to do this (I an object with same > methods as a dict but it is not derived from dict and I want > isinstance(x,dict)==True to use it in place of dict in some other > code). > > What are the problems with the magic trick above? Why does it work?
Normally with __class__ assignment, you would assign to the __class__ attribute of the *instance*, not the class declaration. This actually changes the class of the object, and so isinstance(b, B) would no longer return True. I've never heard of assigning it in the class declaration, and as far as I know, this behavior isn't documented anywhere. I expect that what's happening here is that Python is not actually updating the class of the instance, but that A is merely assigned to the "__class__" attribute in the class dict, and that isinstance is somehow (perhaps accidentally) finding this. So I think this is probably a bug, and I would not rely on it to work correctly in all cases. In any event, the use case that you're looking for is usually accomplished using abstract base classes. Instead of "isinstance(x, dict)", you should use "isinstance(x, collections.MutableMapping)", and then inherit your class from or register it with the MutableMapping ABC. -- http://mail.python.org/mailman/listinfo/python-list