此方法可以愉快地打印出81:
class X:
mypow = pow
print(X().mypow(3, 4))
但是为什么呢?该方法是否没有附加的“自我”参数,应该完全混淆?
为了进行比较,我还使用自己的Pow
函数进行了尝试:
def Pow(x, y, z=None):
return x ** y
class Y:
myPow = Pow
print(Pow(3, 4))
print(Y().myPow(3, 4))
直接函数调用将输出81,并且方法调用按预期崩溃,因为它确实获得了该额外的实例参数:
Python 3: TypeError: unsupported operand type(s) for ** or pow(): 'Y' and 'int'
Python 2: TypeError: unsupported operand type(s) for ** or pow(): 'instance' and 'int'
为什么/为什么Python拥有pow
在这里工作? The documentation没有帮助,我找不到来源。
这是因为用C(内置)定义的python函数具有自动处理的自变量。这是pow函数头文件:
static PyObject *
math_pow(PyObject *self, PyObject *args)
在这里您可以看到self总是由解释器传递。
此行为已连接到method binding。看一下Python告诉您的这些函数/方法:
>> pow
<built-in function pow>
>>> X.mypow
<built-in function pow>
>>> X().mypow
<built-in function pow>
和
>>> Pow
<function Pow at 0x7f88f5715f50>
>>> Y.myPow
<unbound method Y.Pow>
>>> Y().myPow
<bound method Y.Pow of <__main__.Y instance at 0x7f88f57117e8>>
进一步的文档说明:
类字典将方法存储为函数。在类定义中,方法是使用创建功能的常用工具
def
和def
编写的。 [...]为了支持方法调用,函数包括
lambda
方法,用于在属性访问期间绑定方法。这意味着所有函数都是非数据描述符,它们返回绑定方法或非绑定方法,具体取决于是从对象还是从类调用它们。 [...]
但是内置函数没有lambda
方法。这就是为什么__get__()
没有绑定并且可以按照您观察的方式使用,而__get__()
则不能。
[嗯,@ tynn指出了__get__()
没有pow
的原因,因此无法将其转换为Pow
。
但是为什么呢?所有这些事情背后的关键是pow
。如果有人想更好地理解Python,则应该去理解__get__
,这并不难,但非常简单而强大。