@classmethod
和 @staticmethod
在 Python 中是什么意思,它们有什么不同? 我 应该什么时候使用它们,我 为什么 要使用它们,我应该 如何 使用它们?
据我了解, @classmethod
告诉一个类它是一个应该被继承到子类中的方法,或者……什么。然而,这有什么意义呢?为什么不直接定义类方法而不添加 @classmethod
或 @staticmethod
或任何 @
定义?
原文由 user1632861 发布,翻译遵循 CC BY-SA 4.0 许可协议
虽然
classmethod
和staticmethod
非常相似,但两个实体的用法略有不同:classmethod
必须引用类对象作为第一个参数,而staticmethod
可以根本没有参数。例子
解释
让我们假设一个类的例子,处理日期信息(这将是我们的样板):
此类显然可用于存储有关某些日期的信息(没有时区信息;假设所有日期都以 UTC 表示)。
这里我们有
__init__
,一个典型的 Python 类实例的初始化器,它接收参数作为典型的实例方法,具有第一个非可选参数(self
),它包含对 a 的引用新创建的实例。类方法
我们有一些任务可以使用
classmethod
s 很好地完成。假设我们要创建大量
Date
类实例,这些实例具有来自外部源的日期信息,编码为格式为“dd-mm-yyyy”的字符串。假设我们必须在项目源代码的不同位置执行此操作。所以我们必须在这里做的是:
Date
。这看起来像:
为此,C++ 可以通过重载实现这样的功能,但 Python 缺少这种重载。相反,我们可以使用
classmethod
。让我们创建另一个 _构造函数_。让我们更仔细地看一下上面的实现,并回顾一下我们在这里有什么优势:
cls
是 类本身,而不是类的实例。这很酷,因为如果我们继承我们的Date
类,所有的孩子都会有from_string
定义。静态方法
staticmethod
怎么样?它与classmethod
非常相似,但不采用任何强制性参数(就像类方法或实例方法一样)。让我们看下一个用例。
我们有一个想要以某种方式验证的日期字符串。此任务在逻辑上也绑定到我们目前使用的
Date
类,但不需要对其进行实例化。这是
staticmethod
有用的地方。让我们看下一段代码:因此,正如我们从
staticmethod
的用法中看到的那样,我们无法访问类是什么—它基本上只是一个函数,在语法上像方法一样调用,但无法访问对象及其内部结构(字段和其他方法),classmethod
确实有。