分类目录:《系统学习Python》总目录
与函数装饰器一样,不同可调用类型的组合对于类装饰器也有好有坏。考虑文章《系统学习Python——装饰器:基础知识-[类装饰器:实现方法]》例子中类装饰器如下的一个无效替代方案:
def Decorator:
def __init__(self, C):
self.C = C
def __call__(self, *args):
self.wrapped = self.C(*args)
return self
def __getattr__(self, attrname):
return getattr(self.wrapped, attrname)
@decorator
class C: # C = decorator(C)
pass
x = C()
y = C()
这段代码处理多个被装饰的类(每个类都产生一个新的Decorator实例),并且会拦截实例创建调用(每次创建都运行__call__
方法)。然而,和前面的版本不同,这个版本没有能够处理给定类的多个实例一一一每次实例创建调用都覆盖了上一次保存的实例。而之前的版本确实支持多个实例,因为每个实例创建调用都产生了一个新的独立的包装器对象。更通俗地说,如下两种模式中的每一种都支持多个被包装实例:
def decorator(C):
class Wrapper:
def __init__(self, *args):
self.wrapped = C(*args)
return Wrapper
class Wrapper:
pass
def decorator(C):
def onCall(*args):
return Wrapper(C(*args))
return onCall
我们也将在随后一个更为实用的场景中研究这一现象;然而在实际中,我们必须小心地正确组合可调用类型以支持自己的意图,并明智地选择陈述策略。
参考文献:
[1] Mark Lutz. Python学习手册[M]. 机械工业出版社, 2018.