有人可以解释为什么描述符的非函数__get__
属性在调用时似乎会收到一个额外的参数 - 即描述符对象(在函数的情况下隐式传递为self)?
在下面的示例中,B
和C
都是非数据描述符(它们具有__get__
属性)。 B
的{{1}}属性是__get__
的实例 - 可以调用 - 而A
是函数的实例(函数) - 也可以调用。类C
和D
具有名为E
的属性,其类型分别为attr
和B
。
根据我对python属性查找过程的理解,访问C
实例的attr
属性最终会在D/E
中找到attr
并注册它是非数据descriptor将返回在描述符对象上调用D/E.__dict__
的结果 - 但是此调用的签名似乎不同,具体取决于描述符__get__
属性的类型。
我没有针对这种情况的特定用例,但想象__get__
充当一种有状态的函数类我可以从设计的角度看待这种行为是否有意义使A
能够与描述符进行通信。但我不能理解为什么这种行为发生 - 这种行为是隐含的还是我错过了什么?
A
答案 0 :(得分:1)
这与__get__
无关。如果不涉及描述符,您将看到相同的效果:
>>> class A(object):
... def __call__(self, arg):
... return arg
...
>>> a = A()
>>> def b(arg):
... return arg
...
>>> a(3)
3
>>> b(3)
3
问题是A.__call__
是一个未绑定的方法,而一个函数的签名,特定于该函数类型的特定实例,更类似于绑定方法的签名。
您应该将A.__call__
实例的签名与函数的签名进行比较,而不是将A
的签名与单个函数的签名进行比较。如上所示,实例的签名和函数完全匹配。或者,您可以将A.__call__
与types.FunctionType.__call__
进行比较,它将函数实例作为其第一个参数:
>>> import types
>>> types.FunctionType.__call__(b, 3)
3