重写基类方法时如何绕过基类装饰器直接调用未装饰方法
解决方法
你遇到的核心问题是:子类重写带装饰器的方法后,调用super()会触发基类装饰器的旧配置,覆盖子类的新参数。要直接调用基类未被装饰的原始方法,有以下几种可行方案:
方案1:修改基类(最稳定)
把基类里的原始业务逻辑抽成独立的未装饰方法,让装饰后的方法调用它:
class BaseTest: # 这里放未被装饰的原始逻辑 def _test_something(self): do stuff @setup_test(param='foo') def test_something(self): self._test_something()
子类里直接调用这个未装饰的方法即可,完全绕开装饰器的影响:
class NewTest(BaseTest): # 注意:子类必须继承BaseTest,你原代码漏了这一步 @setup_test(param='different value') def test_something(self): super()._test_something()
方案2:利用__wrapped__属性(无需修改基类)
如果你的setup_test装饰器使用了functools.wraps(绝大多数规范的装饰器都会这么做),被装饰的方法会自带__wrapped__属性,指向原始的未装饰方法。直接通过这个属性调用即可:
class NewTest(BaseTest): @setup_test(param='different value') def test_something(self): # 调用基类未被装饰的原始方法 BaseTest.test_something.__wrapped__(self)
可以先通过print(dir(BaseTest.test_something))确认是否存在__wrapped__属性。
方案3:从闭包提取原始方法(极端情况)
如果装饰器没实现__wrapped__,可以尝试从装饰器的闭包中提取原始方法,但这个方法依赖装饰器的内部实现,稳定性差,仅作为兜底方案:
import inspect # 提取基类test_something的原始方法 original_method = None for var in inspect.getclosurevars(BaseTest.test_something).nonlocals.values(): if callable(var) and var.__name__ == 'test_something': original_method = var break class NewTest(BaseTest): @setup_test(param='different value') def test_something(self): if original_method: original_method(self)
内容的提问来源于stack exchange,提问作者wonton
相关产品推荐
相关产品推荐

