在Python中,为什么属性优先于实例属性?

use*_*783 8 python oop properties descriptor

本文介绍Python在执行时如何在对象上查找属性o.a.优先顺序很有趣 - 它寻找:

  1. 作为数据描述符的类属性(最常见的属性)
  2. 实例属性
  3. 任何其他类属性

我们可以使用下面的代码确认这一点,该代码创建一个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会调用该属性).

是否存在"天真"查找顺序会导致问题的不同情况?

fpb*_*bhb 5

Guido van Rossum 本人(Python 的前 BDFL)在 2001 年随 Python 2.2 引入新式类时设计了此功能。其推理在PEP 252中讨论。明确提到了对属性查找的影响:

该方案有一个缺点:在我认为最常见的情况下,引用存储在实例字典中的实例变量,它执行两次字典查找,而经典方案对以两个下划线加一个下划线开头的属性进行了快速测试字典查找。

和:

基准测试证明这实际上与经典实例变量查找一样快,所以我不再担心。