这就是 Python 所做的,以支持向类动态添加函数。
当在函数对象上调用__get__ 时(通常通过类实例上的点访问. 来完成)Python 会将函数转换为方法和隐式 将实例(通常被识别为self)作为第一个参数传递。
在您的情况下,您显式调用__get__并显式传递“实例”2,它被绑定为函数x的第一个参数,这里2被认为是“实例”self:
>>> mul2
<bound method mul of 2>
这会导致在实例 2 上绑定一个方法,其中一个预期参数会产生乘法:调用它会返回 2(分配给 x 的绑定参数)乘以您作为参数 @987654334 提供的任何其他值@。
通常,function() 调用它的 __call__ 并提供适当的参数:
mul.__call__(2, 3) # 6
另外,Python 文档的 Descriptor HOWTO 文档中提供了函数的 Python 实现 __get__。
在这里您可以看到调用__get__ 时发生的转换,使用types.MethodType:
class Function(object):
. . .
def __get__(self, obj, objtype=None):
"Simulate func_descr_get() in Objects/funcobject.c"
return types.MethodType(self, obj, objtype)
感兴趣的访问者的源代码位于Objects/funcobject.c。
如您所见,如果此描述符不存在,您必须在任何时候将函数自动包装到 types.MethodType 中,以便动态地将函数添加到类中,这是不必要的麻烦。