This article描述Python在执行o.a
时如何查找对象的属性。优先顺序很有趣,它寻找:
我们可以使用下面的代码来确认这一点,它创建了一个具有实例属性a
的对象{
class C:
def __init__(self):
self.__dict__['a'] = 1
@property
def a(self):
return 2
o = C()
print(o.a) # Prints 2
为什么Python使用这个优先级顺序而不是“朴素”顺序(实例属性优先于所有类属性)?Python的优先级顺序有一个明显的缺点:它使属性查找变得更慢,因为Python不只是返回一个o
的属性(一个常见的情况),Python必须首先搜索o
的类及其所有超类来查找数据描述符。在
Python的优先级顺序有什么好处?这可能不仅仅适用于上述情况,因为拥有一个实例变量和一个同名的属性在很大程度上是一个小问题(注意需要使用self.__dict__['a'] = 1
来创建instance属性,因为通常的self.a = 1
会调用该属性)。在
“天真”的查找顺序是否会引起问题?在
对于旧样式类(PEP 252):
重写实例dict中的
__dict__
或__class__
将破坏属性查找,并导致实例以极其奇怪的方式运行。在在新样式的类中,Guido选择了以下属性查找实现来保持一致性(PEP 252):
总之,}。因此,属性(数据描述符)优先于实例属性。在
__dict__
和__class__
属性被实现为属性(数据描述符)。为了保持有效状态,实例dict不能重写__dict__
和{Guido van Rossum自己(Python的前BDFL)在2001年python2.2引入新的类时设计了这个特性。推理在PEP 252中讨论。明确提到了对属性查找的影响:
以及:
如果没有比普通实例查找优先的方法,那么如何拦截实例属性访问?这些方法本身不能是实例属性,因为那样会破坏它们的用途(我认为至少没有关于它们的其他约定)。在
除了@timgeb的简洁评论,我无法解释任何比官方的Descriptor How To更好的描述符
相关问题 更多 >
编程相关推荐