radix asked me if I had a blog post about why changing a class from classic to new-style is a bad idea. After I told him that I didn't he insisted that I should write one. Since doing so will take less work than finding something else to distract his attention, here it is:
attribute lookup
Attributes on instances of classic classes override attributes of the same name on their class. For example:
>>> class SimpleDescriptor(object):
... def __get__(self, instance, type):
... print 'getting'
... return instance.__dict__['simple']
... def __set__(self, instance, value):
... print 'setting'
... instance.__dict__['simple'] = value
...
>>> class classic:
... simple = SimpleDescriptor()
...
>>> x = classic()
>>> x.simple = 10
>>> x.simple
10
>>> class newstyle(object):
... simple = SimpleDescriptor()
...
>>> x = newstyle()
>>> x.simple
getting
Traceback (most recent call last):
File "", line 1, in ?
File "", line 4, in __get__
KeyError: 'simple'
>>> x.simple = 10
setting
>>> x.simple
getting
10
As you can see, the descriptor on the new-style class can both handle the setattr and continue to operate after shadowing itself with an instance variable.
Special methods
A particularly interesting consequence of the previous point is that the behavior of special methods changes in some cases:
>>> class x:
... def __init__(self):
... self.__eq__ = lambda other: True
...
>>> x() == 10
True
>>> class x(object):
... def __init__(self):
... self.__eq__ = lambda other: True
...
>>> x() == 10
False
>>>
MRO
Rules for determining the method resolution forbid new-style classes in places where classic classes are acceptable. Consider:
>>> class x: pass
...
>>> class y(object, x): pass
...
>>> class x(object): pass
...
>>> class y(object, x): pass
...
Traceback (most recent call last):
File "", line 1, in ?
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution
order (MRO) for bases object, x
>>>
Hopefully that's enough to satisfy radix. Know of other incompatibilities? Please comment.
No comments:
Post a Comment