You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重写基类方法时如何绕过基类装饰器直接调用未装饰方法

解决方法

你遇到的核心问题是:子类重写带装饰器的方法后,调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 20:35:18