zoukankan      html  css  js  c++  java
  • python装饰器系列(七)

    装饰器 利用__call__方法实现单例

    所谓单例,是指一个类的实例从始至终只能被创建一次。单例的实现有多种,这里以__call__方法来实现

     1 class Single:
     2     __instance = None
     3     
     4     def __init__(self,cls):
     5         self.cls = cls
     6         
     7     def __call__(self,*args,**kwargs):
     8         if self.__instance is None:
     9             self.__instance = self.cls(*args,**kwargs)
    10         return self.__instance
    1 @Single
    2 class Grok1:
    3     pass
    1 grok1 = Grok1()
    2 
    3 id(grok1)
    4 140271956645592
    1 grok2 = Grok1()
    2 
    3 id(grok2)
    4 140271956645592
    1 id(grok1) == id(grok2)
    2 True

    分析一下上边的代码

    1 @Single
    2 class Grok1:
    3     pass
    4 grok1 = Grok1()

    实例化Grok1类时相当于执行了下边两步:

    1 1. Grok1 = Single(Grok1)
    2 2. grok1 = Grok1()

    第一步:执行Single(Grok1)是返回一个Single类的实例,并用一个变量Grok1指向这个实例对象,此时的Grok1不是class Grok1:里的Grok1类,只是名字相同而已,Single类实例化时__init__构建函数被调用,这里会把self.cls这个实例属性指向Grok1类。

    第二步:因Single类实现了__call__方法,所以此实例是一个可调用对象,这里执行grok1 = Grok1(),其中的Grok1已不再是class Grok1:里的类,而是Single类的实例对象,这里调用实例对象就会执行__call__方法

    对此方法中的代码做进一步分析:

    1 def __call__(self,*args,**kwargs):
    2         if self.__instance is None:
    3             self.__instance = self.cls(*args,**kwargs)
    4         return self.__instance

    当第一次调用时,if语句的结果为True,此时会执行self.__instance = self.cls(*args,**kwargs),其中的self.cls指向Grok1类,即这里表示实例化Grok1类,并把self.__instance指向实例化Grok1类的对象,这样__instance就不再是None了,当第二次调用__call__函数时,if语句的结果为False,所以直接执行return self.__instance,所以Grok1这个对象在被多次实例化后指向的实例化对象都是一样的,其实是只被实例化了一次而已

     
     
  • 相关阅读:
    git pull 的时候 把本地的修改 覆盖远程端
    git 把其他分支上的文件拿来覆盖本地
    JS高德地图计算两地之间的实际距离
    C# 微信开发-----微信会员卡(三)激活会员卡
    C# 微信开发-----微信会员卡(二)
    Jquery点击div之外的地方隐藏当前div
    css好看的银行卡号样式
    C# 微信开发-----微信会员卡(一)
    Js操作Array数组
    好看的404代码
  • 原文地址:https://www.cnblogs.com/tianshug/p/10922059.html
Copyright © 2011-2022 走看看