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

     
     
  • 相关阅读:
    Python
    deleted
    deleted
    ZOJ 3593 One Person Game(ExGcd + 最优解)题解
    ZOJ 3609 Modular Inverse(扩展欧几里得)题解
    P2234 [HNOI2002]营业额统计(Splay树)题解
    FJUT seventh的tired树上路径(01字典树)题解
    HDU 4825 Xor Sum(01字典树)题解
    Newcoder Metropolis(多源最短路 + Dijkstra堆优化)题解
    HDU 5938 Four Operations(乱搞)题解
  • 原文地址:https://www.cnblogs.com/tianshug/p/10922059.html
Copyright © 2020-2023  润新知