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

如何实现强制Python子类重写方法时必须调用super()?

实现强制子类调用父类方法的装饰器

要实现类似@abstractmethod的效果,强制子类重写方法时必须调用父类的对应方法,可以自定义@must_call_super装饰器,通过标记状态的方式检查父类方法是否被执行。

完整实现代码

from functools import wraps

def must_call_super(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        # 给实例添加临时标记,记录父类方法是否被调用
        flag_name = f"_called_{func.__name__}"
        setattr(self, flag_name, False)
        # 执行父类原方法
        result = func(self, *args, **kwargs)
        # 检查标记:若未被设为True,说明子类没调用父类方法
        if not getattr(self, flag_name, False):
            raise RuntimeError(f"重写的方法 {func.__name__} 必须调用 super().{func.__name__}()")
        # 清理临时标记
        delattr(self, flag_name)
        return result
    return wrapper

class Foo:
    @must_call_super
    def i_do_things(self):
        print('父类方法被调用')
        # 标记父类方法已执行
        flag_name = f"_called_{self.i_do_things.__name__}"
        setattr(self, flag_name, True)

class Good(Foo):
    def i_do_things(self):
        super().i_do_things()
        print('子类方法也被调用')

class Bad(Foo):
    def i_do_things(self):
        print('子类方法被调用,但未调用父类')

# 正常执行
good = Good()
good.i_do_things()

# 调用方法时触发错误
bad = Bad()
bad.i_do_things()

工作原理

  • 装饰器must_call_super会在父类方法执行前,给实例添加一个初始为False的临时标记。
  • 父类方法内部会把这个标记设为True,证明自身被执行过。
  • 父类方法执行完毕后,装饰器检查标记状态:如果还是False,说明子类重写方法时没有调用父类的super().xxx(),直接抛出运行时错误。
  • 方法执行完成后删除临时标记,避免污染实例属性。

补充说明

  • 这个实现是在方法调用阶段检查,而非类实例化阶段——因为实例化本身不涉及方法执行,只有调用重写后的方法时才会触发检查,这更符合实际使用逻辑。
  • 如果需要在类定义时就做检查,可以借助元类实现,但会增加复杂度,且无法覆盖动态修改方法的场景。

内容的提问来源于stack exchange,提问作者Matt Billman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:35:15