根据Python 2.7.12文档:
如果
__setattr__()
想要分配给实例属性,它应该 不是简单地执行self.name = value
- 这会导致递归 呼唤自己。相反,它应该在字典中插入值 实例属性,例如self.__dict__[name] = value
。 :用于 它不是新的类,而是访问实例字典 应该调用具有相同名称的基类方法,例如,object.__setattr__(self, name, value)
但是,以下代码可以正常运行:
class Class(object):
def __setattr__(self, name, val):
self.__dict__[name] = val;
c = Class()
c.val = 42
print c.val
我知道super(Class, obj).__setattr__(name, value)
可以确保调用所有基类的__setattr__
方法,但经典类也可以从基类继承。那么为什么只推荐新款式?
或者,另一方面,为什么这样做不推荐用于经典课程?
答案 0 :(得分:3)
新式类可能正在使用 slots ,此时没有__dict__
要分配。新式类还支持其他数据描述符,在类上定义的对象,用于处理某些名称的属性设置或删除。
默认情况下,旧式和新式类的实例都有一个属性存储字典。这会浪费具有很少实例变量的对象的空间。在创建大量实例时,空间消耗会变得很严重。
可以通过在新样式类定义中定义
__slots__
来覆盖默认值。__slots__
声明采用一系列实例变量,并在每个实例中保留足够的空间来保存每个变量的值。保存空间是因为没有为每个实例创建__dict__
。
通过在类上添加data descriptors来实现对插槽的访问;每个此类属性都有__set__
和/或__del__
方法的对象。
数据描述符的另一个示例是property()
objects,它附加了setter或deleter函数。在__dict__
中设置与此类描述符对象同名的密钥将被忽略,因为数据描述符会导致属性查找完全绕过__dict__
。
object.__setattr__()
知道如何处理数据描述符,这就是你应该调用它的原因。