在 Python 中,方法主要有三种类型:实例方法、类方法和静态方法。历史上,Python 只支持实例方法(第一个参数是 self)。随着时间的推移,出现了对额外类型的方法的需求:不依赖于对象状态的方法(例如工厂方法)或根本不需要类上下文但在逻辑上属于类的一部分。
问题: 通常需要创建不依赖于对象状态的方法(例如,工厂方法)或根本不需要类上下文,但在逻辑上属于类的一部分。
解决方案: 使用装饰器 @classmethod 和 @staticmethod。
代码示例:
class Example: def instance_method(self): return f'实例:{self}' @classmethod def class_method(cls): return f'类:{cls}' @staticmethod def static_method(): return '静态'
关键特点:
静态方法可以访问类和实例的属性吗?
不,静态方法不会获得对类或对象的引用。
class A: x = 10 @staticmethod def f(): # print(self.x) # 错误 pass
类方法可以在子类中被重写吗?
可以,当通过子类调用 classmethod 时,第一个参数始终是实际类,而不是父类。
class Base: @classmethod def name(cls): return cls.__name__ class Child(Base): pass Child.name() # "Child"
为什么不能在类方法中使用 self?
因为类方法与特定对象无关,而是与整个类相关;没有创建实例,self 无法访问。
将工厂方法定义为 staticmethod,结果试图通过 self 创建类的实例,导致错误或代码重复。
优点:
缺点:
工厂通过 classmethod 声明,内部使用实际类(cls)来创建实例。子类通过该工厂正确创建。
优点:
缺点: