Python 类方法:实例的成员和类的成员有什么区别?



在python中,staticmethod s是"只是函数",我可以用两种不同的方式引用它们:

>>> class A:
...     @staticmethod
...     def f():
...         pass
... 
>>> a=A()
>>> A.f
<function A.f at 0x7f20f8cd3f28>
>>> a.f
<function A.f at 0x7f20f8cd3f28>
>>> a.f is A.f
True

a.fA.f都是引用同一对象的名称,而该对象恰好"只是一个函数"。伟大。

现在,假设我有一个classmethod

>>> class B:
...     @classmethod
...     def f(cls):
...         pass
... 
>>> b=B()
>>> b.f is B.f
False

我知道b.fB.f不是函数:它们是绑定的飞蛾。这意味着cls参数是隐式的,并且始终等于B 。正因为如此,我会理解,如果B2B的子类,B2().f is B().f将是假的,因为它们是具有不同cls参数的绑定方法。但我不明白为什么B().f is B.f会产生False.它们不应该是同一个对象,就像A().fA.f一样吗?

编辑:这个问题与"Python中的@staticmethod和@classmethod有什么区别?"不同。我知道staticmethodclassmethod之间的区别.我想知道一件具体的事情,这在链接的"伞形"问题中没有解决。

B().fB.f是不同的对象,因为每次通过属性访问引用非静态方法时,Python 都会创建一个新的绑定方法对象。

例如,B.f is B.f也是False

>>> B.f is B.f
False

同样,即使实例保持不变,您也会获得一个新的方法对象:

>>> b = B()
>>> b.f is b.f
False

@staticmethod创建一个新的静态方法对象,但是

从类或类检索静态方法对象时 实例中,实际返回的对象是包装的对象,即 不受任何进一步改造的影响。

(来自数据模型)

在这种情况下,A.f始终返回相同的f函数对象。

最新更新