如何在子类中使用基类定义的装饰器?Python技术求助
Python基类装饰器在子类中复用的解决方案
问题本质
你定义的Base.Checkpoint是普通实例方法,类定义阶段调用装饰器时:
- 直接用
@Checkpoint会报错,因为子类作用域里没有这个名称; - 用
@Base.Checkpoint会参数不匹配,因为实例方法要求第一个参数是实例对象,但装饰器调用时传递的是被装饰的函数,导致参数缺失错误。
解决方法1:把Checkpoint改为静态方法
给Base类里的Checkpoint加上@staticmethod装饰,让它脱离实例依赖,直接通过类名调用:
from typing import Any class Base: @staticmethod def Checkpoint(func: Any) -> Any: def inner(self, *args, **kwargs): print(f"calling {func.__name__} from a decorator") return func(self, *args, **kwargs) # 必须调用原函数,否则被装饰方法不会执行 return inner class RegularClass(Base): @Base.Checkpoint def DoSomething1(self): print("Doing something 1") @Base.Checkpoint def DoSomething2(self): print("Doing something 2") # 测试验证 obj = RegularClass() obj.DoSomething1() obj.DoSomething2()
解决方法2:子类内复用装饰器名称
如果不想每次写@Base.Checkpoint,可以在子类内部把基类的装饰器赋值给本地变量,保持原有调用习惯:
from typing import Any class Base: @staticmethod def Checkpoint(func: Any) -> Any: def inner(self, *args, **kwargs): print(f"calling {func.__name__} from a decorator") return func(self, *args, **kwargs) return inner class RegularClass(Base): Checkpoint = Base.Checkpoint # 把基类装饰器引入子类作用域 @Checkpoint def DoSomething1(self): print("Doing something 1") @Checkpoint def DoSomething2(self): print("Doing something 2")
注意点
你原来的装饰器只返回了字符串,没有执行被装饰方法的逻辑,上面的代码补充了return func(self, *args, **kwargs),确保原方法的print语句能正常执行。
内容的提问来源于stack exchange,提问作者scorpion35
相关产品推荐
相关产品推荐

