According to Python 2.7.12 documentation:
If
__setattr__()wants to assign to an instance attribute, it should not simply executeself.name = value— this would cause a recursive call to itself. Instead, it should insert the value in the dictionary of instance attributes, e.g.,self.__dict__[name] = value. For new-style classes, rather than accessing the instance dictionary, it should call the base class method with the same name, for example,object.__setattr__(self, name, value).
However, the following code works as one would expect:
class Class(object):
def __setattr__(self, name, val):
self.__dict__[name] = val;
c = Class()
c.val = 42
print c.val
I know super(Class, obj).__setattr__(name, value) can ensure the __setattr__ methods of all base classes to be called, but classic class can also inherit from bases classes. So why is it only recommended for new style classes?
Or, on the other hand, why is doing so not recommended for classic classes?
New-style classes could be using slots, at which point there is no
__dict__to assign to. New-style classes also support other data descriptors, objects defined on the class that handle attribute setting or deletion for certain names.From the documentation on slots:
Access to slots is instead implemented by adding data descriptors on the class; an object with
__set__and / or__del__methods for each such attribute.Another example of data descriptors are
property()objects that have a setter or deleter function attached. Setting a key with the same name as such a descriptor object in the__dict__would be ignored as data descriptors cause attribute lookup to bypass the__dict__altogether.object.__setattr__()knows how to handle data descriptors, which is why you should just call that.