有人能给我解释一下python中@classmethod
和@staticmethod
的含义吗?我需要知道区别和意义。
据我所知,@classmethod
告诉类它是一个应该继承到子类中的方法,或者。。。一些东西。然而,这又有什么意义呢?为什么不直接定义类方法而不添加@classmethod
或@staticmethod
或任何@
定义呢?
tl;dr:何时应该使用它们,为什么应该使用它们,以及如何使用它们?
我对C++很在行,所以使用更高级的编程概念不应该是个问题。如果可能的话,请给我一个相应的C++示例。
Tags:
@classmethod
表示:当调用此方法时,我们将类作为第一个参数传递,而不是作为该类的实例传递(就像我们通常对方法所做的那样)。这意味着您可以在该方法中使用类及其属性,而不是特定的实例。@staticmethod
意味着:当调用这个方法时,我们不会向它传递类的实例(就像我们通常对方法所做的那样)。这意味着您可以将函数放在类中,但不能访问该类的实例(当您的方法不使用该实例时,这非常有用)。尽管
classmethod
和staticmethod
非常相似,但这两个实体的用法略有不同:classmethod
必须将对类对象的引用作为第一个参数,而staticmethod
则完全没有参数。示例
解释
让我们假设一个类的例子,处理日期信息(这将是我们的样板文件):
这个类显然可以用来存储关于某些日期的信息(没有时区信息;假设所有日期都以UTC表示)。
这里有一个Python类实例的典型初始值设定项
__init__
,它以典型的instancemethod
形式接收参数,第一个非可选参数(self
)保存对新创建实例的引用。类方法
我们有一些任务可以使用
classmethod
很好地完成假设我们要创建许多类实例,其中的日期信息来自外部源,编码为格式为“dd-mm-yyy”的字符串。假设我们必须在项目的源代码中的不同位置执行此操作。
所以我们必须做的是:
Date
。这看起来像:
为此,C++可以实现具有过载的特性,但Python没有这种重载。相反,我们可以使用
classmethod
。让我们创建另一个“构造函数”。让我们更仔细地看一下上面的实现,并回顾一下我们在这里有哪些优势:
cls
是一个保存类本身的对象,而不是类的实例。这很酷,因为如果我们继承我们的Date
类,所有的子类都将定义from_string
。静态方法
那
staticmethod
呢?它与classmethod
非常相似,但不接受任何必需的参数(就像类方法或实例方法那样)。让我们看看下一个用例。
我们有一个日期字符串,我们想以某种方式验证它。这个任务在逻辑上也绑定到我们目前使用的
Date
类,但不需要实例化它。这里是
staticmethod
有用的地方。让我们看下一段代码:因此,正如我们从
staticmethod
的用法中看到的,我们没有任何访问类的权限——它基本上只是一个函数,在语法上称为方法,但没有访问对象及其内部(字段和其他方法)的权限,而classmethod有。罗斯特拉夫·钦科的回答非常恰当。我想我可以强调另一个原因,当您创建一个额外的构造函数时,应该选择
@classmethod
而不是@staticmethod
。在上面的例子中,Rostyslav使用
@classmethod
from_string
作为工厂,从其他不可接受的参数创建Date
对象。对于@staticmethod
也可以这样做,如下代码所示:因此
new_year
和millenium_new_year
都是Date
类的实例。但是,如果您仔细观察,不管怎样,工厂流程都是硬编码来创建
Date
对象的。这意味着,即使Date
类是子类,子类仍然会创建普通的Date
对象(没有子类的任何属性)。请参见下面的示例:datetime2
不是DateTime
的实例吗?世界跆拳道联盟?嗯,那是因为使用了@staticmethod
装饰器。在大多数情况下,这是不希望的。如果您想要的是一个工厂方法,它知道调用它的类,那么
@classmethod
就是您需要的。将
Date.millenium
重写为(这是上面代码中唯一更改的部分):确保
class
不是硬编码的,而是学习的。cls
可以是任何子类。生成的object
将是cls
的一个实例 我们来测试一下:原因是,正如您现在所知道的,使用了
@classmethod
,而不是@staticmethod
相关问题 更多 >
编程相关推荐