在什么场景下要使用类方法

静态方法和类方法的比较

静态方法

我们先来创建一个类,假设他是检测报告的相关信息。

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对象是多态属性,其实类也是有多态的,具体的表现如下

你可能感兴趣的:(python)