根据Python的文档,
带有
__set__()和__get__()定义的数据描述符总是覆盖实例字典中的重定义.
我理解这句话没有问题,但是有人可以为我澄清为什么会有这样的规则吗?毕竟,如果我想覆盖实例字典中的属性,我已经需要明确地执行(inst.__dict__["attr"] = val),因为天真inst.attr = val会调用描述符的__set__方法,这通常会覆盖实例字典中的属性.
编辑:为了说清楚,我理解发生了什么,我的问题是为什么这样的规则到位.
本文介绍Python在执行时如何在对象上查找属性o.a.优先顺序很有趣 - 它寻找:
我们可以使用下面的代码确认这一点,该代码创建一个o具有实例属性的对象a,该类的类包含同名的属性:
class C:
def __init__(self):
self.__dict__['a'] = 1
@property
def a(self):
return 2
o = C()
print(o.a) # Prints 2
Run Code Online (Sandbox Code Playgroud)
为什么Python使用此优先级顺序而不是"天真"顺序(实例属性优先于所有类属性)?Python的优先级顺序有一个明显的缺点:它使属性查找速度变慢,因为oPython必须首先搜索o的类及其所有超类以获取数据描述符,而不仅仅返回if存在的属性(常见情况).
Python的优先顺序有什么好处?它可能不仅仅适用于上述情况,因为拥有一个实例变量和一个同名属性是一个极端情况(注意需要self.__dict__['a'] = 1用来创建实例属性,因为通常self.a = 1会调用该属性).
是否存在"天真"查找顺序会导致问题的不同情况?