@classmethod是 Python 的内置装饰器,用来定义类方法。
类方法的特点是:调用时,第一个参数不是实例 self,而是类本身 cls。
1. 普通实例方法
普通方法第一个参数是self:
pythoninstance method
class User: def hello(self): print(self)
调用:
实际等价于:
所以self是实例对象。
2. 类方法 @classmethod
类方法第一个参数通常写成cls:
class User: @classmethod def create(cls): print(cls) return cls()
调用:
实际等价于:
User.create()// Python 自动把 User 传给 cls
所以:
3. 最小例子
class A: @classmethod def show_class(cls): print(cls)A.show_class()
输出类似:
也就是说,cls拿到的是类对象A。
4. 和 self 的区别
class A: def instance_method(self): print("self =", self) @classmethod def class_method(cls): print("cls =", cls)a = A()a.instance_method()A.class_method()
输出概念上:
self = <__main__.A object at 0x...>cls = <class '__main__.A'>
区别是:
5. @classmethod 常见用途:替代构造函数
最常见用途是写“命名构造器”。
比如:
class User: def __init__(self, name: str, age: int): self.name = name self.age = age @classmethod def from_dict(cls, data: dict): return cls( name=data["name"], age=data["age"], )
使用:
user = User.from_dict({ "name": "Alice", "age": 18})
等价于:
但是from_dict的语义更清楚。
6. 为什么不用 staticmethod
如果写成普通函数也能创建对象:
class User: @staticmethod def from_dict(data): return User(data["name"], data["age"])
但这里硬编码了User。
如果以后有子类:
调用:
Admin.from_dict({"name": "Bob", "age": 20})
staticmethod 版本
返回的是:
classmethod 版本
返回的是:
这就是 @classmethod 的优势:支持继承和多态构造。
7. 继承例子
class User: def __init__(self, name): self.name = name @classmethod def from_name(cls, name): return cls(name)class Admin(User): passu = User.from_name("Alice")a = Admin.from_name("Bob")print(type(u))print(type(a))
输出:
<class '__main__.User'><class '__main__.Admin'>
因为:
User.from_name("Alice") cls = UserAdmin.from_name("Bob") cls = Admin
总结
@classmethod 的优势在于它将类本身(cls)作为参数传递,从而解耦了类名与构造逻辑。这使得设计模式中的“工厂方法(Factory Method)”在面对类继承时,能够保持完美的灵活性和可扩展性。