Python类装饰器是通过实现__call__方法使类可调用,从而在不修改原类前提下动态增强其行为,常用于自动注册、接口校验、属性注入及单例控制等场景。

Python 类装饰器本质上是利用 __call__ 方法实现的可调用对象,它通过元编程思想,在不修改原类定义的前提下,动态增强类的行为——比如自动注册、添加属性、注入方法或控制实例化过程。
类装饰器的核心:让类本身可被调用
要让一个类能像函数一样被用作装饰器(即写成 @MyDecorator),它必须实现 __call__ 方法。该方法接收被装饰的类作为参数,并返回一个新的类(或原类增强后的版本)。
- 装饰器类通常在
__init__中接收配置参数(如日志开关、注册名等) -
__call__接收被装饰的目标类,可对其进行包装、子类化或动态改写 - 返回值一般是一个新类(常继承原类),确保实例化行为不受破坏
常见用途:自动注册与接口校验
类装饰器特别适合框架层的统一管理场景,例如插件系统中自动将类注册到全局 registry,或强制要求实现特定方法。
- 注册型:在
__call__中执行registry[cls.__name__] = cls - 校验型:检查
cls是否有run或handle方法,缺失则抛出TypeError - 注入型:用
setattr(cls, 'created_at', datetime.now())添加元数据
注意实例生命周期与单例控制
类装饰器本身是“类”,每次使用 @Deco() 都会新建一个装饰器实例;而 @Deco(无括号)则复用同一个类对象。若需共享状态(如计数器、缓存),应把状态放在装饰器类的类属性或闭包中,而非实例属性。
立即学习“Python免费学习笔记(深入)”;
- 错误做法:
self.count = 0→ 每次装饰都重置 - 正确做法:
Deco._registry = {}或用模块级变量 - 若想控制被装饰类的实例化(如单例),可在返回的新类中重写
__new__
和函数装饰器、@dataclass 的关键区别
函数装饰器作用于函数对象,类装饰器作用于类对象;二者都属于运行时元编程,但操作目标不同。它不是替代 @dataclass 的工具——@dataclass 是语言内置的代码生成机制(编译期/导入期),而类装饰器是纯运行期逻辑,更灵活但也更“手动”。
-
@dataclass自动生成__init__、__repr__等,不可定制流程 - 类装饰器可决定是否保留原
__init__、是否拦截__new__、是否代理属性访问 - 两者可共存:先
@dataclass再@MyClassDecorator
TypeError: isinstance() arg 2 must be a type or tuple of types 类似错误。











