python classmethod 和 staticmethod
Contents
Intro
在 stackoverflow
上看到讲解 staticmethod
和 classmethod
之间区别的回答,翻译整理一下。
对于 classmethod
修饰的函数,必须接收一个 class object
作为第一个参数,而 staticmethod
可以不带参数。用一个具体的例子说明二者之间的区别:
class Date(object):
def __init__(self, day=0, month=0, year=0):
self.day = day
self.month = month
self.year = year
@classmethod
def from_string(cls, date_as_string):
day, month, year = map(int, date_as_string.split('-'))
date1 = cls(day, month, year)
return date1
@staticmethod
def is_date_valid(date_as_string):
day, month, year = map(int, date_as_string.split('-'))
return day <= 31 and month <= 12 and year <= 3999
def display(self):
return "{0}-{1}-{2}".format(self.month, self.day, self.year)
# 通过类名来调用
date2 = Date.from_string('11-09-2012')
is_date = Date.is_date_valid('11-09-2012')
# 通过类实例来调用
print(date2.is_date_valid('11-09-2012'))
date3 = date2.from_string('10-09-2012')
print(date3.display())
在这个例子中,from_string
是一个 classmethod
, 它的作用是,按指定格式的字符串来初始化一个 Date
对象。在 Date
的 __init__
函数中定义了初始化一个 Date
对象所需要的参数,如果这里我们想通过给出一个字符串来初始化得到一个 Date
对象,我们首先需要将这个字符串解析出 day
, month
, year
的内容,然后将这些内容传入 Date
的 __init__
来初始化得到 Date
对象:
day, month, year = map(int, string_date.split('-'))
date1 = Date(day, month, year)
在 C++
中,可以通过重载构造函数的方式,来实现这个目的。而在 python
里面,没有提供重载构造函数的功能,因此需要借助 classmethod
, 来实现这一 feature. 在上面的例子中,Date.from_string
返回的也是一个 Date
对象。这就相当于我们有了两种创建一个 Date
对象的手段,一是直接使用 Date()
, 这将调用 __init__
函数,二是显式地通过 Date.from_string
, 它从格式化的字符串中创建一个 Date
对象。
而这里的 is_date_valid
函数是一个 staticmethod
, 它用于检查构造日期的字符串是否合法,它的参数中,不包含 class object 或者 instance object. 它和一个普通的函数并没有太多区别,只是为这个类提供了一些 helper function
.
无论是 staticmethod
还是 classmethod
, 子类都可以继承。
在使用 staticmethod
或 classmethod
的时候,都可以通过类名或者实例来调用。
Author Li Xunsong
LastMod 2021-09-19