python 属性的获取和设置顺序是什么?

What is the python attribute get and set order?

Python为我们提供了很多关于instance/class属性的可能性,例如:

class A(object):
    def __init__(self):
        self.foo = "hello"

a = A()

有很多方法可以access/changeself.foo的值:

  1. 直接访问a.foo
  2. 内部字典a.__dict__['foo']
  3. 获取和设置a.__get__a.__set__,当然有两个是预定义的方法。
  4. 获取属性a.__getattribute__
  5. __getattr____setattr__
  6. 也许更多。

在阅读源代码时,我总是搞不清楚它们的最终访问顺序是什么?当我使用 a.foo 时,我怎么知道哪个 method/attribute 会被实际调用?

bar = a.foo...

  1. 调用 a.__getattribute__('foo')
  2. 默认情况下依次查找 a.__dict__['foo']
  3. 或调用 foo.__get__()(如果在 A 上定义)。

返回的值将被分配给 bar


a.foo = bar...

  1. 调用 a.__getattribute__('foo')
  2. 默认情况下依次查找 a.__dict__['foo']
  3. 或调用 foo.__set__(bar) 如果定义在 A.

我发现 this great post 对 object/class 属性查找有详细的解释。

对于对象属性查找:

假设 Class 是 class 并且 instanceClass 的实例,评估 instance.foobar 大致等同于:

  • 调用 Class.__getattribute__ (tp_getattro) 的类型槽。默认情况下这样做:
    • Class.__dict__ 是否有一个 foobar 项目是数据描述符?
      • 如果是,return Class.__dict__['foobar'].__get__(instance, Class) 的结果。
    • instance.__dict__ 里面有 'foobar' 项吗?
      • 如果是,return instance.__dict__['foobar'].
    • Class.__dict__ 是否有 foobar 项不是数据描述符 [9]?
      • 如果是,return Class.__dict__['foobar'].__get__(instance, klass) 的结果。 [6]
  • 如果仍未找到该属性,并且存在 Class.__getattr__,请调用 Class.__getattr__('foobar')

这里有一张插图:

如果有兴趣请查看原始博客,其中对 python class、属性查找和元 class.

进行了出色的解释