定义Python类方法时是否必须使用@classmethod装饰器?
问题解答
1. ppr方法的实际类型
你定义的ppr本质上只是挂载在Test类命名空间下的普通函数,不属于实例方法、类方法、静态方法三者中的任何一类,原因如下:
- Python中类内的方法类型由绑定逻辑决定,而非仅看调用是否成功:
- 实例方法:实例访问时自动绑定
self为第一个参数,要求定义时至少接收1个位置参数 - 类方法:类/实例访问时自动绑定
cls为第一个参数,要求用@classmethod装饰 - 静态方法:类/实例访问时都不自动绑定任何参数,要求用
@staticmethod装饰
- 实例方法:实例访问时自动绑定
- 你通过
Test.ppr()调用成功,只是因为直接访问类命名空间下的原始函数对象,没有触发任何绑定逻辑,刚好符合ppr无参数的定义;而通过实例调用时触发了实例方法的默认绑定逻辑,自动把实例作为第一个参数传入,才会触发参数数量不匹配的报错。
2. 定义类方法是否必须加@classmethod装饰器
必须加,你遇到的场景不能作为「类方法不需要装饰器」的依据,真正的类方法有两个核心特征,ppr都不满足:
- 调用时自动传入类本身作为第一个
cls参数,无需手动传参 - 既支持通过类调用,也支持通过实例调用,实例调用时会自动取实例所属的类作为
cls参数传入
你可以对比下面的测试代码验证:
class Test: # 普通函数(你定义的ppr) def ppr(): print('ppr called') # 真正的类方法 @classmethod def real_cm(cls): print(f'real classmethod called, cls is {cls}') # 1. 普通函数用实例调用直接报错 inst = Test() try: inst.ppr() except Exception as e: print(f'inst.ppr()报错:{e}') # 输出参数不匹配报错 # 2. 真正的类方法用实例也能正常调用 inst.real_cm() # 正常运行,自动传入cls参数 Test.real_cm() # 正常运行,自动传入cls参数
内容的提问来源于stack exchange,提问作者showkey
相关产品推荐
相关产品推荐

