我们先来创建一个类,假设他是检测报告的相关信息。
class Report:
inspection = "negative"
def __init__(self, name, id_number):
self.name = name
self.id_number = id_number
那么这个类就很简单,他有检查结果,被检测者的名字和number等信息。那么此时我们想加一个方法,其实这个方法更类本身并无关系(也就是说这个函数可以),但是出于业务的需要,我们把这个方法写在该类里面更好的管理。
假设这个方法需要计算当前日期和输入日期的差值。
@staticmethod
def calculation_diff_time(history_time):
history_time = datetime.strptime(history_time, "%Y-%m-%d %H:%M:%S")
diff_seconds = (datetime.now() - history_time).seconds
print(f"时间已过去{diff_seconds//60}小时")
我们来看一下这个方法的调用。
Report("", "").calculation_diff_time("2022-05-01 09:00:00")
print("不实例化")
Report.calculation_diff_time("2022-05-01 09:00:00")
时间已过去754小时
不实例
时间已过去754小时
我们可以看到,静态方法无论实例不实例均可调用。并且因为没有实例函数的传递,静态方法不能调用类方法和实例方法。
总结来说,静态方法和对象本身并无关系,只是因为某种联系写在类里。类中应尽量规避过多的静态方法,因为这面向对象的思想有所违背。
但是依稀记得以前看过的一篇博客,提到静态方法同样是面对对象,面对的是类的本身,有利于多态。这里笔者水平有限,还是认为应该规避静态方法的使用,除非必要。
我们再来看一下类方法,我们在上述的静态方法上略作改变。
@classmethod
def reader_report(cls, history_time):
history_time = datetime.strptime(history_time, "%Y-%m-%d %H:%M:%S")
diff_seconds = (datetime.now() - history_time).seconds
print(f"时间已过去{diff_seconds // 60}小时 结果{cls.inspection}")
Report("", "").reader_report("2022-05-01 09:00:00")
print("不实例化")
Report.reader_report("2022-05-01 09:00:00")
时间已过去830小时 结果negative
不实例化
时间已过去830小时 结果negative
同样无论是否实例化,类方法均可调用,并且我们发现类方法可以调用类属性。我们再来试试实例属性和方法。
@classmethod
def reader_report(cls, history_time):
history_time = datetime.strptime(history_time, "%Y-%m-%d %H:%M:%S")
diff_seconds = (datetime.now() - history_time).seconds
print(f"{cls.name}时间已过去{diff_seconds // 60}小时 结果{cls.inspection}")
Report("lisan", "").reader_report("2022-05-01 09:00:00")
AttributeError: type object 'Report' has no attribute 'name'
显然这里面的cls只是传递的类和并非对象,所以实例属性无法调用。我们再来试试方法是否可以调用。
@classmethod
def reader_report(cls, history_time):
history_time = datetime.strptime(history_time, "%Y-%m-%d %H:%M:%S")
diff_seconds = (datetime.now() - history_time).seconds
print(f"时间已过去{diff_seconds // 60}小时 结果{cls.inspection}")
cls.calculation_diff_time("2022-05-02 09:00:00")
print("调用静态方法成功")
cls.say_hello()
print("方法调用成功")
时间已过去851小时
调用静态方法成功
Report("lisan", "").reader_report("2022-05-01 09:00:00")
File "E:/project_views/reader/ss.py", line 31, in reader_report
cls.say_hello()
TypeError: say_hello() missing 1 required positional argument: 'self'
我们可以看到类方法只能调用静态方法,和无法调用其他方法。那么类方法在什么场景下更适合使用呢。
我们来看一下这个方法的名字,类方法。那么使用场景无疑很简单了。
@classmethod
def a_new_init(cls, name, id_number):
return cls(name, id_number)
report = Report("lisan", "")
print(report.name)
print(id(report))
report = report.a_new_init("liuliu", None)
print(report.name)
print(id(report))
lisan
2036243181296
liuliu
2036243181240
我们可以看到调用实例方法,可以返回一个新类,那么该方法的第一个用法就是构建类。
那么我们来做下总结。
用处一 类方法可以作为类中对象的创建来使用,在不改变构造函数的情况下。可以为对象的创建提供多个入口。艺达到具体的使用用途。
我们都知道python对象是多态属性,其实类也是有多态的,具体的表现如下