【问题标题】:Why metaclass __getattribute__ invoked here?为什么在这里调用元类 __getattribute__?
【发布时间】:2016-07-27 08:53:28
【问题描述】:

这是从 Python 2.7.12 文档中检索到的代码 sn-p(3.4.12. 新型类的特殊方法查找¶):

除了绕过任何实例属性之外 正确性,隐式特殊方法查找一般也会绕过 对象元类的__getattribute__() 方法:

>>> class Meta(type):
...    def __getattribute__(*args):
...       print "Metaclass getattribute invoked"
...       return type.__getattribute__(*args)
...
>>> class C(object):
...     __metaclass__ = Meta
...     def __len__(self):
...         return 10
...     def __getattribute__(*args):
...         print "Class getattribute invoked"
...         return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__()                 # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c)          # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c)                      # Implicit lookup
10

我的问题是,为什么在执行type(c).__len__(c) 时会调用元类__getattribute__

由于type(c) 产生C,该语句可以重写为C.__len__(c)C.__len__是类C中定义的未绑定方法,在C.__dict__中可以找到,那么为什么Meta会参与查找呢?

【问题讨论】:

    标签: python python-2.7 class attributes


    【解决方案1】:

    引自同一文档,3.4.2.1。新式类的更多属性访问:

    object.__getattribute__(self, name)

    调用无条件来实现属性访问 类的实例。 ...

    C 类是元类Meta 的一个实例,所以Meta.__getattribute__ 在访问C.__len__ 时会被调用,尽管后者可以在C.__dict__ 中找到。

    其实访问C.__dict__也是一种属性访问,所以Meta.__getattribute__还是会被调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-19
      • 2017-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多