用 @staticmethod
@classmethod
的函数有什么区别?
原文由 Daryl Spitzer 发布,翻译遵循 CC BY-SA 4.0 许可协议
用 @staticmethod
@classmethod
的函数有什么区别?
原文由 Daryl Spitzer 发布,翻译遵循 CC BY-SA 4.0 许可协议
静态 方法是一种对调用它的类或实例一无所知的方法。它只是获取传递的参数,没有隐式的第一个参数。它在 Python 中基本上没有用——您可以只使用模块函数而不是静态方法。
另一方面, classmethod 是一种方法,它通过调用它的类或调用它的实例的类作为第一个参数。当您希望方法成为类的工厂时,这很有用:因为它获取调用它的实际类作为第一个参数,所以您始终可以实例化正确的类,即使涉及子类。例如,观察类方法 dict.fromkeys()
如何在子类上调用时返回子类的实例:
>>> class DictSubclass(dict):
... def __repr__(self):
... return "DictSubclass"
...
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>>
原文由 Thomas Wouters 发布,翻译遵循 CC BY-SA 4.0 许可协议
4 回答4.4k 阅读✓ 已解决
4 回答3.8k 阅读✓ 已解决
3 回答2.1k 阅读✓ 已解决
1 回答4.4k 阅读✓ 已解决
1 回答3.8k 阅读✓ 已解决
1 回答2.8k 阅读✓ 已解决
2 回答2k 阅读✓ 已解决
也许一些示例代码会有所帮助:注意
foo
,class_foo
和static_foo
的调用签名的差异:下面是对象实例调用方法的常用方式。对象实例
a
被隐式传递为第一个参数。使用 classmethods ,对象实例的类作为第一个参数隐式传递,而不是
self
。您也可以使用该类调用
class_foo
。实际上,如果您将某个东西定义为类方法,那可能是因为您打算从类中调用它,而不是从类实例中调用它。A.foo(1)
会引发 TypeError,但A.class_foo(1)
工作正常:人们发现类方法的一种用途是创建 可继承的替代构造函数。
使用 staticmethods ,
self
(对象实例)和cls
(类)都不会作为第一个参数隐式传递。它们的行为类似于普通函数,只是您可以从实例或类中调用它们:静态方法用于对与类与类有某种逻辑联系的函数进行分组。
foo
只是一个函数,但是当你调用a.foo
你不只是得到这个函数,你得到一个带有对象实例的函数的“部分应用”版本a
绑定为函数的第一个参数。foo
需要 2 个参数,而a.foo
只需要 1 个参数。a
绑定到foo
。这就是下文“绑定”一词的含义:With
a.class_foo
,a
is not bound toclass_foo
, rather the classA
is bound toclass_foo
.在这里,使用静态方法,即使它是一个方法,
a.static_foo
只是返回一个没有参数绑定的良好 ‘ole 函数。static_foo
需要 1 个参数,而a.static_foo
也需要 1 个参数。当然,当您使用
A
类调用static_foo
时,也会发生同样的事情。