我正在读书 一个演讲 在Pythons的对象模型中,在一张幻灯片中(数字 9),作者断言Pythons的功能是描述符。他提出的例子类似于我写的这个例子:
def mul(x, y):
return x * y
mul2 = mul.__get__(2)
mul2(3) # 6
现在,我明白了这一点,因为函数定义了一个 __get__ 它是我在Python文档的描述部分中描述的描述符。
我不明白的是调用是如何产生输出的。
我正在读书 一个演讲 在Pythons的对象模型中,在一张幻灯片中(数字 9),作者断言Pythons的功能是描述符。他提出的例子类似于我写的这个例子:
def mul(x, y):
return x * y
mul2 = mul.__get__(2)
mul2(3) # 6
现在,我明白了这一点,因为函数定义了一个 __get__ 它是我在Python文档的描述部分中描述的描述符。
我不明白的是调用是如何产生输出的。
这就是Python为了支持动态地向类添加函数而做的工作。
什么时候 __get__ 在函数对象上调用(通常通过点访问来完成) . 在类的实例上)Python将函数转换为 方法 和 隐式 传递实例(通常被认为是 self)作为第一个论点。
在你的情况下,你 明确地 呼叫 __get__ 和 明确地 通过'实例' 2 它被绑定为函数的第一个参数 x, 这里 2 被认为是“实例” self:
>>> mul2
<bound method mul of 2>
这导致在实例2上绑定一个方法,其中一个预期参数产生乘法:调用它返回 2 (分配给的绑定参数 x)乘以你提供的任何其他参数作为参数 y。
一般, function() 调用它 __call__ 提供适当的论据:
mul.__call__(2, 3) # 6
作为一个加号,Python的实现 __get__ 功能提供在 描述符HOWTO Python文档的文档。
在这里你可以看到转换,使用 types.MethodType,那发生在 __get__ 被调用:
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 任何时候你想要动态地向类添加一个函数,这是一个不必要的麻烦。