【问题标题】:How do function descriptors work?函数描述符如何工作?
【发布时间】:2023-03-09 10:57:01
【问题描述】:

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

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

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

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

我不明白调用所提供的输出究竟是如何产生的。

【问题讨论】:

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


    【解决方案1】:

    这就是 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 中,以便动态地将函数添加到类中,这是不必要的麻烦。

    【讨论】:

      猜你喜欢
      • 2023-04-06
      • 1970-01-01
      • 2011-10-28
      • 1970-01-01
      • 2018-06-08
      • 2011-04-28
      • 1970-01-01
      • 2011-01-14
      相关资源
      最近更新 更多