Python 中 class method 与 static method 的区别与联系

本文深入解析Python中的classmethod与staticmethod,阐述两者在硬编码与软编码上的核心差异,并通过实例展示如何选择合适的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很多编程语言中是没有 class method 而言的,比如 Java,但是 Python 语言中却提供了两种看似相同又不同的关键字。
这里我们不扣字眼,比如说 class method 与 static method 的区别有方法前面的 @ 符号不同,我们仅给出最为核心的不同点。

相同点

class method 和 static method 都用于表示属于类的方法

区别(重点)

  1. static method 会硬编码

所谓硬编码就是说,方法中返回的类名必须与当前的 class 名称一致。

  1. 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

  1. 当方法需要传入当前的类名,返回值又和当前类名绑定,此时应该选择 class method。
  2. 当进行一些类相关的操作,但是又不需要绑定类名,此时应该选择 static method。
Python中,方法可以被定义为静态方法静态方法类相关联的方法,但不需要访问类的实例或类的任何属性。静态方法可以通过在方法上使用@staticmethod装饰器来定义。静态方法可以通过类名直接调用,而不需要创建类的实例。 在给定的代码示例中,eat方法是一个普通的实例方法,而不是静态方法。要将eat方法定义为静态方法,可以在方法上添加@staticmethod装饰器,如下所示: ```python @staticmethod def eat(): print("eat food") ``` 这样,eat方法就成为了一个静态方法,可以通过类名直接调用,而不需要创建类的实例。例如: ```python Person.eat() ``` 请注意,静态方法不会自动传递任何参数,因此在静态方法中无法访问类的实例或类的属性。如果需要访问类的属性或实例,可以考虑使用类方法或实例方法。 引用: \[1\] class_a.py \[2\] 个人经验 \[3\] Python官方文档 #### 引用[.reference_title] - *1* *2* [Python核心编程(二)](https://blog.youkuaiyun.com/qq_42475194/article/details/108094759)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [【PythonPython’s super() considered super!](https://blog.youkuaiyun.com/qq_29757283/article/details/118391059)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值