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这个对象在被多次实例化后指向的实例化对象都是一样的,其实是只被实例化了一次而已

     
     
  • 相关阅读:
    luogu P1833 樱花 看成混合背包
    luogu P1077 摆花 基础记数dp
    luogu P1095 守望者的逃离 经典dp
    Even Subset Sum Problem CodeForces
    Maximum White Subtree CodeForces
    Sleeping Schedule CodeForces
    Bombs CodeForces
    病毒侵袭持续中 HDU
    病毒侵袭 HDU
    Educational Codeforces Round 35 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/tianshug/p/10922059.html
Copyright © 2011-2022 走看看