8

鉴于:

In [37]: class A:
   ....:     f = 1
   ....:

In [38]: class B(A):
   ....:     pass
   ....:

In [39]: getattr(B, 'f')
Out[39]: 1

好的,那要么调用 super 要么爬取 mro?

In [40]: getattr(A, 'f')
Out[40]: 1

这是意料之中的。

In [41]: object.__getattribute__(A, 'f')
Out[41]: 1

In [42]: object.__getattribute__(B, 'f')
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-42-de76df798d1d> in <module>()
----> 1 object.__getattribute__(B, 'f')

AttributeError: 'type' object has no attribute 'f'

什么是 getattribute 不做 getattr 做的?

In [43]: type.__getattribute__(B, 'f')
Out[43]: 1

什么?! type.__getattribute__调用 super 但object's 版本没有?

In [44]: type.__getattribute__(A, 'f')
Out[44]: 1
4

1 回答 1

9

您直接在 classes上操作。object.__getattribute__仅用于and的实例。那是因为在 type 上查找了特殊方法;例如,类型是类。AB

那么对于类,类型是.. type

>>> class A:
...     f = 1
... 
>>> class B(A):
...     pass
... 
>>> type(B)
<class 'type'>

所以type.__getattribute__使用:

>>> type.__getattribute__(B, 'f')
1

object.__getattribute__在实例上正常工作:

>>> object.__getattribute__(B(), 'f')
1

对于实例属性,首先在类上查找(在数据描述符的情况下),然后在实例上查找,如果实例没有属性,则按 MRO 顺序搜索类层次结构。这是 的工作object.__getattribute__。因此,object.__getattribute__查看属性的第一个参数(例如self,实例对象),查看 中的对象type(self).__mro__

对于类,属性是在类本身及其所有基础上查找的;type.__getattribute__直接看self.__mro__这些;self在这里是一个类对象。

如果你使用object.__getattribute__那么直接f没有属性,没有任何地方。如果您使用,是其中的成员,因此可以在此处找到:B ftype(B).__mro__type.__getattribute__AB.__mro__f

>>> type(B).__mro__
(<class 'type'>, <class 'object'>)
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
于 2014-06-10T21:21:29.923 回答