为什么`class X:mypow = pow`起作用?那`self`呢?

问题描述 投票:7回答:3

此方法可以愉快地打印出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没有帮助,我找不到来源。

python methods self
3个回答
5
投票

这是因为用C(内置)定义的python函数具有自动处理的自变量。这是pow函数头文件:

static PyObject * math_pow(PyObject *self, PyObject *args)在这里您可以看到self总是由解释器传递。


2
投票

此行为已连接到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>>

进一步的文档说明:

类字典将方法存储为函数。在类定义中,方法是使用创建功能的常用工具defdef编写的。 [...]

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

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


0
投票

[嗯,@ tynn指出了__get__()没有pow的原因,因此无法将其转换为Pow

但是为什么呢?所有这些事情背后的关键是pow。如果有人想更好地理解Python,则应该去理解__get__,这并不难,但非常简单而强大。

© www.soinside.com 2019 - 2024. All rights reserved.