Python 中 class method 与 static method 的区别
很多编程语言中是没有 class method 而言的,比如 Java,但是 Python 语言中却提供了两种看似相同又不同的关键字。
这里我们不扣字眼,比如说 class method 与 static method 的区别有方法前面的 @ 符号不同,我们仅给出最为核心的不同点。
相同点
class method 和 static method 都用于表示属于类的方法
区别(重点)
- static method 会硬编码
所谓硬编码就是说,方法中返回的类名必须与当前的 class 名称一致。
- class method 是软编码
class method 传递的第一个参数使 cls ,cls 默认绑定了当前的类名。
举个例子
class Date:
# 构造函数
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
def tomorrow(self):
self.day += 1
@staticmethod
def parse_from_string(date_str):
year, month, day = tuple(date_str.split("-"))
return Date(int(year), int(month), int(day))
@staticmethod
def valid_str(date_str):
year, month, day = tuple(date_str.split("-"))
if int(year) > 0 and (int(month) > 0 and int(month) <= 12) and (int(day) > 0 and int(day) <= 31):
return True
else:
return False
@classmethod
def from_string(cls, date_str):
year, month, day = tuple(date_str.split("-"))
return cls(int(year), int(month), int(day))
def __str__(self):
return "{year}/{month}/{day}".format(year=self.year, month=self.month, day=self.day)
if __name__ == "__main__":
new_day = Date(2018, 12, 31)
new_day.tomorrow()
print(new_day)
# 2018-12-31
date_str = "2018-12-31"
year, month, day = tuple(date_str.split("-"))
new_day = Date(int(year), int(month), int(day))
print(new_day)
# 用staticmethod完成初始化
new_day = Date.parse_from_string(date_str)
print(new_day)
# 用classmethod完成初始化
new_day = Date.from_string(date_str)
print(new_day)
print(Date.valid_str("2018-12-32"))
从上面的例子,我们可以看到:static method 返回的对象是 Date,而 class method 方法返回的是 cls, cls 默认绑定到了当前的 Date 类名。此时,如果我们修改了 Date 类名为 NewDate,那么 static method 还需要手工再次修改返回的类名,而 class method 就不需要手动修改类名了,因为 cls 始终绑定的都是所属的类名。
class method 是否能够替代 static method 方法呢?
答案是毫无疑问不能。
我们还是以上面的例子看,如果需要进行日期字符串校验,此时我们并不需要传入当前的类名,也就不需要使用 class method 了。因为上面的 valid_str 方法被定义成 static method。
Conclusion
- 当方法需要传入当前的类名,返回值又和当前类名绑定,此时应该选择 class method。
- 当进行一些类相关的操作,但是又不需要绑定类名,此时应该选择 static method。