为什么仅在新样式 类 中支持 object.__setattr__(self, name, value)?
Why favor object.__setattr__(self, name, value) only in new style classes?
根据 Python 2.7.12 文档:
If __setattr__()
wants to assign to an instance attribute, it should
not simply execute self.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)
.
但是,下面的代码可以正常工作:
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)
可以确保调用所有base class的__setattr__
方法,但是classic class也可以继承自碱基 classes。那么为什么它只推荐用于新样式 classes?
或者,另一方面,为什么不建议 classic classes 这样做?
新式 classes 可能正在使用 slots,此时没有 __dict__
可以分配给。新式 classes 还支持其他 数据描述符 ,在 class 上定义的对象,用于处理某些名称的属性设置或删除。
By default, instances of both old and new-style classes have a dictionary for attribute storage. This wastes space for objects having very few instance variables. The space consumption can become acute when creating large numbers of instances.
The default can be overridden by defining __slots__
in a new-style class definition. The __slots__
declaration takes a sequence of instance variables and reserves just enough space in each instance to hold a value for each variable. Space is saved because __dict__
is not created for each instance.
通过在 class 上添加 data descriptors 来实现对插槽的访问;每个此类属性具有 __set__
和/或 __del__
方法的对象。
数据描述符的另一个示例是 property()
objects,它附加了 setter 或删除函数。在 __dict__
中设置与此类描述符对象同名的键将被忽略,因为数据描述符会导致属性查找完全绕过 __dict__
。
object.__setattr__()
知道如何处理数据描述符,这就是为什么你应该调用它。
根据 Python 2.7.12 文档:
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)
.
但是,下面的代码可以正常工作:
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)
可以确保调用所有base class的__setattr__
方法,但是classic class也可以继承自碱基 classes。那么为什么它只推荐用于新样式 classes?
或者,另一方面,为什么不建议 classic classes 这样做?
新式 classes 可能正在使用 slots,此时没有 __dict__
可以分配给。新式 classes 还支持其他 数据描述符 ,在 class 上定义的对象,用于处理某些名称的属性设置或删除。
By default, instances of both old and new-style classes have a dictionary for attribute storage. This wastes space for objects having very few instance variables. The space consumption can become acute when creating large numbers of instances.
The default can be overridden by defining
__slots__
in a new-style class definition. The__slots__
declaration takes a sequence of instance variables and reserves just enough space in each instance to hold a value for each variable. Space is saved because__dict__
is not created for each instance.
通过在 class 上添加 data descriptors 来实现对插槽的访问;每个此类属性具有 __set__
和/或 __del__
方法的对象。
数据描述符的另一个示例是 property()
objects,它附加了 setter 或删除函数。在 __dict__
中设置与此类描述符对象同名的键将被忽略,因为数据描述符会导致属性查找完全绕过 __dict__
。
object.__setattr__()
知道如何处理数据描述符,这就是为什么你应该调用它。