为什么`class X:mypow = pow`有效?怎么样'自我'?

Ste*_*ann 7 python methods self

这工作并愉快地打印81:

class X:
    mypow = pow

print(X().mypow(3, 4))
Run Code Online (Sandbox Code Playgroud)

但为什么?是不是给出了额外的"自我"论证的方法,应该完全混淆?

为了比较,我也尝试了我自己的Pow功能:

def Pow(x, y, z=None):
    return x ** y

class Y:
    myPow = Pow

print(Pow(3, 4))
print(Y().myPow(3, 4))
Run Code Online (Sandbox Code Playgroud)

直接函数调用打印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'
Run Code Online (Sandbox Code Playgroud)

Pythons为什么/如何pow在这里工作?文档没有帮助,我找不到来源.

小智 5

这是因为在C(builtins)中定义的python函数具有自动处理的自参数.这是pow函数头:

static PyObject * math_pow(PyObject *self, PyObject *args) 在这里你可以看到自我总是由翻译传递.


tyn*_*ynn 3

此行为与方法绑定有关。看看 Python 告诉你关于这些函数/方法的内容:

>> pow
<built-in function pow>
>>> X.mypow
<built-in function pow>
>>> X().mypow
<built-in function pow>
Run Code Online (Sandbox Code Playgroud)

>>> Pow
<function Pow at 0x7f88f5715f50>
>>> Y.myPow
<unbound method Y.Pow>
>>> Y().myPow
<bound method Y.Pow of <__main__.Y instance at 0x7f88f57117e8>>
Run Code Online (Sandbox Code Playgroud)

文件进一步指出:

类字典将方法存储为函数。在类定义中,方法是使用def和 来编写的lambda,这是创建函数的常用工具。[...]

为了支持方法调用,函数包括__get__()在属性访问期间绑定方法的方法。这意味着所有函数都是非数据描述符,它们返回绑定或未绑定方法,具体取决于它们是从对象还是类调用。[...]

但内置函数没有方法__get__()。这就是为什么pow没有绑定并且可以按照您观察到的方式使用,而Pow不能。