函数描述符如何工作?

时间:2016-08-30 13:22:30

标签: python python-2.7 function python-3.x descriptor

我在Pythons'上阅读a presentation对象模型,在一张幻灯片(编号9)中,作者断言Pythons'函数是描述符。他举例说明的例子与我写的这个例子类似:

def mul(x, y):
    return x * y

mul2 = mul.__get__(2)
mul2(3) # 6

现在,我明白了这一点,因为函数定义了__get__,它是一个描述符,正如我在Python文档的描述部分所描述的那样。

我不明白的是,呼叫到底是如何产生输出的。

1 个答案:

答案 0 :(得分:16)

Python的功能是为了支持动态地向类添加函数。

在函数对象上调用__get__时(通常通过点访问.在类的实例上完成),Python会将函数转换为方法和< em>隐式将实例(通常被识别为self)作为第一个参数传递。

在您的情况下,明确地致电__get__明确地传递&#39;实例&#39; 2绑定为函数x的第一个参数,此处2被视为&#34;实例&#34; self

>>> mul2
<bound method mul of 2> 

这导致绑定在实例2上的方法,其中一个预期参数产生乘法:调用它返回2(分配给x的绑定参数)乘以您提供的任何其他值论证y

通常情况下,function()会使用提供的相应参数调用它__call__

mul.__call__(2, 3)  # 6

作为一个优点,Python文档的Descriptor HOWTO文档中提供了函数__get__的Python实现。

您可以在此处查看调用__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中自动包装函数,只要您想要动态地将一个函数添加到类中,这是一个不必要的麻烦。