类装饰器是用类实现的装饰器,通过__call__方法使实例可调用,天然支持状态保持与参数扩展;带参形式需外层接收参数、内层封装逻辑;虽非元编程本身,但常作为其轻量入口,可协同__set_name__、元类等实现动态行为修改。
类装饰器是用类来实现的装饰器,它通过实现 __call__ 方法,让实例可以像函数一样被调用。与函数装饰器不同,类装饰器天然支持状态保持(比如计数、缓存、配置),也更容易扩展初始化参数和生命周期逻辑。
要让类能当装饰器用,关键在于定义 __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") 这种带参形式,需多嵌套一层:外层类接收装饰器参数,内层类接收被装饰对象。本质是「返回装饰器类的实例」而非直接实例化。
示例:
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() 动态创建类 等机制。
例如,用类装饰器自动为方法添加性能计时,再通过元类批量注册到监控中心——这就是典型的元编程组合用法。