【发布时间】:2016-12-05 13:23:50
【问题描述】:
根据 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__方法被调用,但是经典类也可以继承自基类。那么为什么只推荐用于新样式类呢?
或者,另一方面,为什么不建议在经典课程中这样做?
【问题讨论】:
-
那么为什么它只推荐用于新样式类? 调用
__setattr__而不是直接对实例字典进行操作允许超类对正在发生的事情进行一些“监督”。将此方法视为新样式类的优势。它可能会推荐给所有类,但不继承没有具有可调用__setattr__方法的超类的旧式类。 -
@jedwards 是的,因为经典课程没有
classobj.__setattr__,新风格课程只有object.__setattr__。 -
你完全正确。我的观点是,我查看了您以粗体表示的句子,而不是直接使用 instance dict 的气馁(正如您所展示的,它在许多情况下都可以正常工作,并且正如 Martijn 所展示的那样,在某些情况下它不会),但更多的是鼓励使用
__setattr__,它允许超类一些*监督和使用更新的特性,如描述符。对不起,如果我不清楚:)
标签: python class inheritance setattr new-style-class