根据this answer:
setattr(instance, name, value)
is syntactic sugar forinstance.__setattr__(name, value)
但是:
class C:
def __init__(self):
# OK.
super().__setattr__("foo", 123)
# AttributeError: 'super' object has no attribute 'foo'
setattr(super(), "foo", 123)
c = C()
什么给予?他们不应该做同样的事情吗?在
你提到的答案掩盖了一些重要的细节。长话短说,
setattr
绕过了super
的魔力,因此它试图在super()
代理对象本身上设置属性,而不是在self
上设置属性。在setattr(a, b, c)
不是a.__setattr__(b, c)
的语法糖。^仔细搜索相反,},并且它检查实例dict,除非{}说不。在
a.__setattr__(b, c)
只是对__setattr__
执行常规的属性查找,所以它要经过__getattribute__
和{super
实现一个自定义的__getattribute__
方法来实现其属性魔术。super().__setattr__
使用这个钩子,查找C
的超类__setattr__
并绑定{self
上的属性。在setattr(super(), ...)
绕过__getattribute__
。它执行前面提到的直接MRO搜索,通过super
的MRO进行搜索,得到一个方法对象,用于在超级实例本身上设置属性。super
实例没有存储任意属性数据的__dict__
,因此尝试设置foo
属性失败,并返回一个TypeError
。在相关问题 更多 >
编程相关推荐