类装饰器是实现非侵入式扩展最自然可控的方式,通过在类定义时拦截__new__、__init__或直接添加属性/方法来增强行为,不修改原类、无需继承,且比元类更轻量易测。

类的装饰器是实现非侵入式扩展最自然、最可控的方式之一——它不修改原始类定义,也不要求继承或重写调用方代码,而是在类被定义时“悄悄增强”其行为。
核心思路:在类构造阶段注入逻辑
类装饰器本质是一个可调用对象(函数或类),接收目标类作为参数,返回增强后的类(或就地改造)。关键不是改“类怎么写”,而是改“类怎么被创建和初始化”:
- 拦截 __init__:动态包装构造逻辑,添加日志、时间戳、初始化检查等(如自动记录
created_at) - 拦截 __new__:控制实例生成过程,实现单例、原型缓存、参数校验等
- 直接向 cls 添加属性或方法:比如统一加
version类属性、dump_schema()类方法 - 避免在装饰器中做耗时操作:类装饰发生在模块导入时,影响启动性能
典型场景与写法示例
以 Python 为例,常见非侵入式扩展可这样落地:
-
自动日志与元信息注入:装饰器为每个实例添加
log_init()和created_at,无需每类都写重复逻辑 -
接口契约增强:检查类是否实现了必需方法(如
validate()或serialize()),缺失则抛出清晰错误 - 权限/环境约束:根据运行环境(dev/staging/prod)自动禁用某些危险方法,或强制要求字段加密
-
指标埋点注册:自动将类名、方法签名上报到监控系统,无需手动调用
metrics.track()
注意组合性与兼容性
多个类装饰器可以叠加使用,但需注意执行顺序和副作用:
- 装饰器之间应尽量无状态、无全局副作用,便于测试和复用
- 若原类有父类,
__init__包装中务必保留super().__init__调用链,否则继承逻辑断裂 - 动态添加的方法绑定在实例上(如
self.log_init),不是类方法;如需类级能力,直接赋值给cls - 比起元类,类装饰器更轻量、调试友好,也更容易单元测试——你可以单独传入一个 dummy 类验证行为
它和 AOP、Go 中间件的本质一致
虽然语言机制不同,但思想相通:把横切关注点(日志、监控、事务、权限)从核心业务中剥离。Python 类装饰器对应 AOP 中的“类级别切面”,Go 的接口代理或 HTTP 中间件是其在静态类型语言中的等效实践。区别只在于语法载体,而非设计意图。

















