类装饰器是实现了__call__方法的类,用于修饰其他类或函数,支持状态保存和参数配置,比函数装饰器更灵活;典型应用包括调用监控、类注册和接口约束。

类装饰器是 Python 元编程中非常实用的工具,它让类本身具备“修饰其他类或函数”的能力,比函数装饰器更灵活,也更适合封装状态和复用逻辑。
什么是类装饰器
类装饰器是一个实现了 __call__ 方法的类。当它被用作装饰器(即写在 @ 后面)时,Python 会实例化该类,并在被装饰对象定义完成后,自动调用其实例的 __call__ 方法,传入被装饰的目标(函数或类)。
关键点:
- 必须定义 __init__ 接收被装饰对象(如 func 或 cls)
- 必须定义 __call__ 来执行实际的增强逻辑
- 返回值通常是包装后的新可调用对象(如闭包、新函数或代理类)
类装饰器 vs 函数装饰器
函数装饰器简洁,适合无状态的通用逻辑(如日志、计时);类装饰器天然支持保存配置和内部状态,适合需要初始化参数或跨调用维护数据的场景。
立即学习“Python免费学习笔记(深入)”;
例如:统计某个方法被调用了多少次,每次调用都记录时间戳——这类需求用类装饰器更自然:
PHP5学习对象教程由美国人古曼兹、贝肯、瑞桑斯编著,简张桂翻译,电子工业出版社于2007年12月1日出版的关于PHP5应用程序的技术类图书。该书全面介绍了PHP 5中的新功能、编程方法及设计模式,还分析阐述了PHP 5中新的数据库连接处理、错误处理和XML处理等机制,帮助读者系统了解、熟练掌握和高效应用PHP。
- 实例属性可存调用次数、历史列表等状态
- __init__ 可接收配置参数(如是否启用调试、阈值限制)
- __call__ 决定如何包装原行为(前置/后置处理、条件跳过、异常捕获等)
典型应用场景
1. 方法调用监控与增强
给类方法添加统一的输入校验、性能打点、权限检查。例如:@TimeIt 记录耗时,@Retry(max_times=3) 自动重试失败调用。
2. 类注册与元信息注入
在类定义时自动将其注册到全局工厂或插件池中,同时注入版本、作者、描述等元数据。
3. 接口契约约束
强制被装饰类实现特定方法、满足协议(Protocol),或对 __init__ 参数做运行时校验。
一个可复用的类装饰器示例
下面是一个带参数的类装饰器,用于限制方法调用频率(简单令牌桶):
class RateLimit:
def __init__(self, max_calls=5, window=60):
self.max_calls = max_calls
self.window = window
self.calls = []
def __call__(self, func):
def wrapper(*args, **kwargs):
now = time.time()
# 清理过期记录
self.calls = [t for t in self.calls if now - t < self.window]
if len(self.calls) >= self.max_calls:
raise RuntimeError("Rate limit exceeded")
self.calls.append(now)
return func(*args, **kwargs)
return wrapper
使用方式:
@RateLimit(max_calls=3, window=10)
def api_call(): ...
注意:这个例子中 calls 状态是共享的——因为所有被同一 RateLimit 实例装饰的方法共用一个 self.calls。如需每个方法独立限流,应在 wrapper 内部维护状态,或改用装饰器工厂模式。










