当前位置:   article > 正文

系统学习Python——装饰器:类装饰器-[单例类:编写替代方案]

系统学习Python——装饰器:类装饰器-[单例类:编写替代方案]

分类目录:《系统学习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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

参考文献:
[1] Mark Lutz. Python学习手册[M]. 机械工业出版社, 2018.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/136480
推荐阅读
相关标签
  

闽ICP备14008679号