我正在读书 一个演讲 在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
任何时候你想要动态地向类添加一个函数,这是一个不必要的麻烦。