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

时间:2015-06-21 03:42:10

标签: python class attributes metaprogramming instance-variables

Python为instance / class属性提供了许多可能性,例如:

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

a = A()

有多种方法可以访问/更改self.foo

的值
  1. 直接访问a.foo
  2. 内部字典a.__dict__['foo']
  3. 获取并设置a.__get__a.__set__,当然有两种是预先定义的方法。
  4. getattribute a.__getattribute__
  5. __getattr____setattr__
  6. 或许更多。
  7. 在阅读源代码时,我总是迷失在他们的最终访问顺序之外?当我使用a.foo时,我如何知道实际调用哪个方法/属性?

2 个答案:

答案 0 :(得分:8)

bar = a.foo ...

  1. 调用a.__getattribute__('foo')
  2. 默认情况下会查找a.__dict__['foo']
  3. 如果在foo上定义,则
  4. 或调用.__get__() A
  5. 然后将返回的值分配给bar

    a.foo = bar ...

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

答案 1 :(得分:6)

我发现this great post有关于对象/类属性查找的详细说明。

对象属性查找:

假设Class是该类,而instanceClass的实例,则评估instance.foobar大致相当于此:

  • 调用Class.__getattribute__tp_getattro)的类型位置。默认设置为:
    • Class.__dict__是否有foobar项是数据描述符?
      • 如果是,请返回Class.__dict__['foobar'].__get__(instance, Class)的结果。
    • instance.__dict__中是否有'foobar'个项目?
      • 如果是,请返回instance.__dict__['foobar']
    • Class.__dict__是否有foobar项不是数据描述符[9]?
      • 如果是,请返回Class.__dict__['foobar'].__get__(instance, klass)的结果。 [6]
  • 如果仍未找到该属性,并且Class.__getattr__,请致电Class.__getattr__('foobar')

有一个插图图片:

enter image description here

如果感兴趣,请查看原始博客,其中提供了有关python类,属性查找和元类的出色解释。