赞
踩
分类目录:《系统学习Python》总目录
有趣的是,这里如果能使用nonlocal
语句(仅在Python3.X中可用)来改变外层作用域名称,我们在这里可以编写一个自包含程度更高的解决方案一一一下面的替代方案为每个类使用了一个外层作用域,而不是为每个类使用一个全局表入口,并实现了同样的效果。虽然这工作起来相同,但是它不依赖装饰器外的全局作用域中的变量名(注意这里的None
检查可以使用is
而不是==
,但是无论采用哪种方式,它们实现的功能都是一个很平常的测试):
def singleton(aClass):
instances = None
def onCall(*args, **kwargs):
nonlocal instances
if instances is None:
instances = aClass(*args, **kwargs)
return instances
return onCall
在Python3.X或Python2.X(2.6及之后的)版本中,我们也可以用函数属性或类编写一个自包含的解决方案。下面代码中的第一段编写了前者,它利用了每个装饰都会有一个onCall
函数的事实一一对象命名空间充当了与外层作用域相同的角色。下面代码中的第二段为每次装饰使用一个实例,而不是使用一个外层作用域、函数对象或全局表。实际上,第二段代码依赖于相同的编程模式,随后我们会看到这是一个常见的装饰器类错误。这里我们只想要一个实例,但情况并不经常是这样:
def singleton(aClass): def onCall(*args, **kwargs): onCall.instances is None: onCall.instances = aClass(*args, **kwargs) return instances onCall.instances = None return onCall class singleton: def __init__(self, aCkass): self.aCkass = aCkass self.instances = None def __call__(self, *args, **kwargs): if self.instances is None: self.instances = self.aCkass(*args, **kwargs) return self.instances
参考文献:
[1] Mark Lutz. Python学习手册[M]. 机械工业出版社, 2018.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。