Python 类方法 : what's the difference between a member of an instance and a member of the class?

标签 python static-methods

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

>>> 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 不是函数:它们是绑定(bind)方法。这意味着 cls 参数是隐式的,并且总是等于 B。因此,我会理解如果 B2B 的子类,则 B2().f is B().f 将是false,因为它们是具有不同 cls 参数的绑定(bind)方法。但我不明白为什么 B().f is B.f 会产生 False。它们不应该是同一个对象,就像 A().fA.f 一样吗?

编辑:这个问题与“What is the difference between @staticmethod and @classmethod in Python?”不同。我知道 staticmethodclassmethod 之间的区别。我想知道一件具体的事情,这在链接的“伞”问题中没有解决。

最佳答案

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

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

>>> B.f is B.f
False

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

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

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

When a static method object is retrieved from a class or a class instance, the object actually returned is the wrapped object, which is not subject to any further transformation.

(来自 Data model)

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

关于Python 类方法 : what's the difference between a member of an instance and a member of the class?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36802411/

相关文章:

python - 我们如何将 numpy 数组的两列连接成一列,并用空格分隔值?

python - 使用字典时循环无法正确迭代

python - 猜字游戏 -- 这还能写得更好吗?

python - staticmethod() 有什么神奇的作用,使得静态方法总是在没有实例参数的情况下被调用?

java - 计算完美数

python - 如何避免 mypy 检查明确排除但导入的模块_without_ 手动添加 `type:ignore`(自动生成)?

python - Pandas 的年化返回率

java - 静态方法是 DI 反模式吗?

java - 为什么 BindingAdapter 必须是静态方法?

c# - 静态类的静态方法如何知道调用者?