python 为什么cls.__getattribute__返回函数而不是绑定方法,而cls.__call__返回绑定方法

qoefvg9y  于 2023-03-21  发布在  Python
关注(0)|答案(1)|浏览(152)

假设cls是python中的一个类。cls.__getattribute__返回在object上定义的__getattribute__函数,但它没有将cls绑定到这个函数。根据描述符协议,clsobject的一个示例,如果在类字典上找到一个属性,它应该返回一个绑定了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>
vkc1a9a2

vkc1a9a21#

当您在cls的超类object上查找cls.__getattribute__时,可以在cls自己的MRO中找到它。与通过这种方式找到的任何其他方法一样,查找返回一个表示该类示例的__getattribute__方法的未绑定方法。
另一方面,当你查找cls.__call__时,在cls的MRO中找不到它。cls的MRO是(cls, object)clsobject都没有定义__call__方法。相反,这个方法在cls自己的类中找到,它的 * 元类 *:它在type上被找到。与以这种方式找到的任何其他方法一样,结果方法被绑定到查找发生的示例,该示例是cls本身。
因此,cls.__getattribute__表示获取cls示例属性的未绑定方法,而cls.__call__表示调用cls本身的绑定方法。

相关问题