类方法必须带cls参数并用@classmethod装饰,支持继承和多态;静态方法用@staticmethod装饰,无隐式参数,不参与继承。

类方法必须带 cls 参数,静态方法完全不接收隐式参数
类方法用 @classmethod 装饰,Python 自动把调用者类(不是父类,也不是硬编码的类名)作为第一个参数传入,名字习惯叫 cls。这意味着你能在方法里安全读写 cls.some_class_attr,或调用 cls.another_classmethod()。
静态方法用 @staticmethod 装饰,它根本没隐式参数——既没有 self,也没有 cls。它就是个普通函数,只是被放在类里归类而已。
- 误写成
def from_json(cls, data)却忘了加@classmethod?会报TypeError: from_json() missing 1 required positional argument: 'cls' - 写了
@staticmethod却在函数里用了cls.config?直接NameError: name 'cls' is not defined - 想让子类复用逻辑但用了静态方法?子类调用时还是执行原函数,
cls的动态绑定能力彻底丢失
类方法支持继承和多态,静态方法不参与继承链
当你在子类上调用类方法,cls 指向的是子类本身;而静态方法不管谁调用,代码体一模一样,不会随调用者变化。
典型场景:工厂方法。比如 Date.from_iso("2024-01-01") 返回 Date 实例,但 DateTime.from_iso("2024-01-01T12:00") 应该返回 DateTime 实例——只有类方法能做到这点。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 类方法中写
return Date(...)是错的:子类调用仍返回父类实例 - 静态方法里硬编码
Date.config或Date.create_db_conn(),子类无法覆盖,只能复制粘贴整段逻辑 - 类属性计数器(如
cls._created_count += 1)必须用类方法,否则子类调用会改错对象
什么时候该用 @staticmethod?只有一种情况
仅当这个函数:纯计算、无状态、不访问任何类或实例数据、也不打算被子类定制——才适合 @staticmethod。
常见例子:is_valid_email()、to_celsius(f)、parse_csv_line(line)。它们跟类有关联(比如属于某个领域),但不需要知道“我是哪个类”。
- 函数里出现任何
MyClass.X、MyClass.do_something(),就说明它不该是静态方法 - 哪怕当前没用到
cls,只要未来可能读类变量、创建实例、或支持子类扩展,就该先写@classmethod - 把工具函数全塞进类里却不加装饰器?那它们其实是实例方法,调用时会报
missing 1 required positional argument: 'self'
调用方式相同,语义和风险天差地别
MyClass.method() 和 obj.method() 都能成功调用类方法和静态方法,但背后机制完全不同:
- 类方法:无论怎么调,
cls始终是实际调用者类(obj.__class__) - 静态方法:不传任何隐式参数,
obj.method()和MyClass.method()完全等价 - 最隐蔽的坑:有人把数据库连接池初始化写成静态方法,结果上线后子类换驱动失败,因为初始化逻辑根本不感知类继承关系
真正难的不是语法,而是判断“这个逻辑是否需要感知类身份”。一旦选错,问题往往静默发生——运行不报错,但子类行为错得离谱。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










