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

如何在重写方法时保留父类方法的装饰器

解决子类重写方法自动复用父类装饰器的问题

这个问题我之前也碰到过——父类的方法带了装饰器,子类重写时总不想每次都手动加装饰器,也不想用super()来绕弯子。核心就是要让装饰器的逻辑能自动作用在子类的重写方法上,下面给你两个实用的方案:

方案一:模板方法模式(简单直观)

我们可以把父类带装饰器的method_a作为固定入口,子类只需要重写一个约定好的内部方法(比如_method_a),父类的method_a会自动调用这个内部方法,这样装饰器的逻辑就不会被子类覆盖了。

def decorator(method):
    def wrapper(self, *args, **kwargs):
        print("how are you ?")
        method(self, *args, **kwargs)
    return wrapper

class A:
    @decorator
    def method_a(self, *args, **kwargs):
        # 固定调用子类重写的内部方法
        self._method_a(*args, **kwargs)
    
    def _method_a(self, *args, **kwargs):
        # 父类默认实现
        pass

class B(A):
    def _method_a(self, *args, **kwargs):
        print("Fine thanks !")

class_b = B()
class_b.method_a()

运行这段代码就能得到你想要的输出:

how are you ?
Fine thanks !

这个方案的好处是逻辑清晰,不需要理解复杂的元类知识,子类只需要按照约定重写_method_a就行,完全不用关心装饰器的存在。

方案二:元类自动添加装饰器(保持原有接口)

如果你希望子类还是能直接重写method_a,不用改方法名,那可以用元类来实现——元类能在类定义的阶段自动给指定方法加上装饰器。

def decorator(method):
    def wrapper(self, *args, **kwargs):
        print("how are you ?")
        method(self, *args, **kwargs)
    return wrapper

class DecoratorMeta(type):
    def __new__(cls, name, bases, attrs):
        # 检查当前类是否定义了method_a,如果是就自动加装饰器
        if 'method_a' in attrs:
            attrs['method_a'] = decorator(attrs['method_a'])
        return super().__new__(cls, name, bases, attrs)

class A(metaclass=DecoratorMeta):
    @decorator
    def method_a(self, *args, **kwargs):
        pass

class B(A):
    def method_a(self, *args, **kwargs):
        print("Fine thanks !")

class_b = B()
class_b.method_a()

这个方案里,子类的写法和你原来的完全一样,元类会在背后自动给method_a加上装饰器,完美满足“不用super()、不用重新定义装饰器”的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:32:26