Python类装饰器实现_元编程解析【教程】

11次阅读

类装饰器是用类实现的装饰器,通过__call__方法使实例可调用,天然支持状态保持与参数扩展;带参形式需外层接收参数、内层封装逻辑;虽非元编程本身,但常作为其轻量入口,可协同__set_name__、元类等实现动态行为修改。

Python类装饰器实现_元编程解析【教程】

什么是类装饰器

类装饰器是用类来实现的装饰器,它通过实现 __call__ 方法,让实例可以像函数一样被调用。与函数装饰器不同,类装饰器天然支持状态保持(比如计数、缓存、配置),也更容易扩展初始化参数和生命周期逻辑。

基础写法:一个可调用的类

要让类能当装饰器用,关键在于定义 __call__ 方法,并在初始化时接收被装饰对象(函数或方法):

  • __init__ 中保存被装饰的目标(如函数)
  • __call__ 中实现实际增强逻辑(如前置/后置操作、包装调用)
  • 返回结果通常要调用原函数,也可拦截或改写行为

示例:

class LogCall:     def __init__(self, func):         self.func = func         self.count = 0 
def __call__(self, *args, **kwargs):     self.count += 1     print(f"[Log] Calling {self.func.__name__} (#{self.count})")     return self.func(*args, **kwargs)

@LogCall def say_hello(name): return f"Hello, {name}!"

带参数的类装饰器

若想支持 @LogCall(level="DEBUG") 这种带参形式,需多嵌套一层:外层类接收装饰器参数,内层类接收被装饰对象。本质是「返回装饰器类的实例」而非直接实例化。

立即学习Python免费学习笔记(深入)”;

  • 外层 __init__ 接收装饰器参数(如 level、verbose)
  • 外层 __call__ 返回真正的装饰器类实例(即接收 func 的那一层)
  • 内层类负责保存 func 并定义实际调用逻辑

示例:

class LogCall:     def __init__(self, level="INFO"):         self.level = level 
def __call__(self, func):     # 返回一个真正执行装饰的类实例     class Wrapper:         def __init__(self, f):             self.func = f             self.count = 0          def __call__(self, *args, **kwargs):             self.count += 1             print(f"[{self.level}] {self.func.__name__} called {self.count} time(s)")             return self.func(*args, **kwargs)     return Wrapper(func)

@LogCall(level="DEBUG") def add(a, b): return a + b

类装饰器与元编程的关系

类装饰器本身不是元编程,但它常作为元编程的轻量入口——因为它在类/函数定义后、使用前介入,能动态修改行为。真正体现元编程的是配合 __set_name__、描述符、__getattribute__type() 动态创建类 等机制。

  • 可结合 __set_name__ 实现属性级装饰(如验证字段)
  • 可在 __call__ 中动态生成方法、注入属性,甚至重写 __dict__
  • metaclass 协同时,能在类创建阶段统一应用装饰逻辑

例如,用类装饰器自动为方法添加性能计时,再通过元类批量注册到监控中心——这就是典型的元编程组合用法。

text=ZqhQzanResources