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

如何在Python 3.6+中批量装饰类的所有方法?

批量给类方法添加装饰器的Python3.6+实现

方案1:类装饰器(推荐,直观灵活)

类装饰器能在类定义完成后批量修改方法,我们可以写一个通用工具,接收目标装饰器和方法匹配规则,自动给符合条件的方法套上装饰器。

通用类装饰器实现

def decorate_methods(decorator, method_check):
    def class_wrapper(cls):
        # 遍历类的所有属性,筛选出符合条件的方法
        for name, method in list(cls.__dict__.items()):
            if callable(method) and method_check(name):
                setattr(cls, name, decorator(method))
        return cls
    return class_wrapper

给类C的f1-f10应用装饰器

用这个工具处理类C,匹配规则设为“方法名以'f'开头,后缀是1-10的数字”:

def function_decorator(fn):
    def wrapper(*args, **kwargs):
        print('decorated')
        return fn(*args, **kwargs)
    return wrapper

@decorate_methods(function_decorator, lambda name: name.startswith('f') and name[1:].isdigit() and 1 <= int(name[1:]) <=10)
class C:
    def f1(self):
        pass

    def f2(self):
        pass

    # ... 省略f3到f9方法

    def f10(self):
        pass

    def other_method(self):  # 这个方法不会被装饰
        pass

测试验证:

c = C()
c.f1()  # 输出: decorated
c.f10() # 输出: decorated
c.other_method()  # 无输出

方案2:元类(底层控制类创建过程)

元类可以在类被定义的阶段就完成方法装饰,适合需要更底层控制的场景。

带参数的元类实现

class DecoratorMeta(type):
    def __new__(cls, name, bases, attrs, decorator=None, method_check=None):
        if decorator and method_check:
            for attr_name, attr_value in attrs.items():
                if callable(attr_value) and method_check(attr_name):
                    attrs[attr_name] = decorator(attr_value)
        return super().__new__(cls, name, bases, attrs)

给类C应用元类

定义类时通过metaclass参数指定元类,同时传入装饰器和匹配规则:

class C(metaclass=DecoratorMeta, decorator=function_decorator, method_check=lambda name: name.startswith('f') and name[1:].isdigit() and 1<=int(name[1:])<=10):
    def f1(self):
        pass

    def f10(self):
        pass

    def other_method(self):
        pass

子类继承父类方法的场景处理

如果父类包含通用方法,不同子类需要用不同装饰器,类装饰器的方式更灵活——给每个子类单独指定对应的装饰器即可:

示例代码

# 父类:包含通用方法f1-f10
class Parent:
    def f1(self):
        print("Parent f1")
    
    def f2(self):
        print("Parent f2")
    
    # ... 省略f3到f10方法

# 不同装饰器
def decorator1(fn):
    def wrapper(*args, **kwargs):
        print('--- Decorated by decorator1 ---')
        return fn(*args, **kwargs)
    return wrapper

def decorator2(fn):
    def wrapper(*args, **kwargs):
        print('=== Decorated by decorator2 ===')
        return fn(*args, **kwargs)
    return wrapper

# 子类1:用decorator1装饰继承的方法
@decorate_methods(decorator1, lambda name: name.startswith('f') and name[1:].isdigit() and 1<=int(name[1:])<=10)
class Child1(Parent):
    pass

# 子类2:用decorator2装饰继承的方法
@decorate_methods(decorator2, lambda name: name.startswith('f') and name[1:].isdigit() and 1<=int(name[1:])<=10)
class Child2(Parent):
    pass

测试验证:

c1 = Child1()
c1.f1()
# 输出:
# --- Decorated by decorator1 ---
# Parent f1

c2 = Child2()
c2.f2()
# 输出:
# === Decorated by decorator2 ===
# Parent f2

注:如果子类重写了父类的方法,类装饰器也会自动装饰重写后的方法,符合预期。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:10:33