假设cls
是python中的一个类。cls.__getattribute__
返回在object
上定义的__getattribute__
函数,但它没有将cls
绑定到这个函数。根据描述符协议,cls
是object
的一个示例,如果在类字典上找到一个属性,它应该返回一个绑定了cls
的绑定方法。
使用cls.__call__
的相同调用返回一个绑定方法,其中cls
绑定到type
上定义的__call__
函数。为什么有区别?为什么cls.__getattribute__
找不到type
中的属性?
class cls:
pass
[In]: cls.__getattribute__
[Out]: slot wrapper '__getattribute__' of 'object' objects>
[In]: object.__getattribute__
[Out]: <slot wrapper '__getattribute__' of 'object' objects>
[In]: cls.__getattribute__ is object.__getattribute__
[Out]: True
[In]: cls.__call__
[Out]: <method-wrapper '__call__' of type object at 0x7fdee07ad110>
[In]: type.__call__.__get__(cls)
[Out]: <method-wrapper '__call__' of type object at 0x7fdee07ad110>
1条答案
按热度按时间vkc1a9a21#
当您在
cls
的超类object
上查找cls.__getattribute__
时,可以在cls
自己的MRO中找到它。与通过这种方式找到的任何其他方法一样,查找返回一个表示该类示例的__getattribute__
方法的未绑定方法。另一方面,当你查找
cls.__call__
时,在cls
的MRO中找不到它。cls
的MRO是(cls, object)
,cls
和object
都没有定义__call__
方法。相反,这个方法在cls
自己的类中找到,它的 * 元类 *:它在type
上被找到。与以这种方式找到的任何其他方法一样,结果方法被绑定到查找发生的示例,该示例是cls
本身。因此,
cls.__getattribute__
表示获取cls
示例属性的未绑定方法,而cls.__call__
表示调用cls
本身的绑定方法。