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

     
     
  • 相关阅读:
    hdu 2842 Chinese Rings
    Codeforces Round #118 (Div. 1) A 矩阵快速幂
    hdu2604 Queuing
    支付宝 生活号 获取 userId 和 生活号支付
    maven 项目使用本地jar
    nexus 私有 maven 仓库的搭建
    linux jdk 安装
    gitlab 可以上传代码,但是 不能 上传 tag 问题
    maven 内置变量
    mysql 不允许分组的问题 this is incompatible with sql_mode=only_full_group_by
  • 原文地址:https://www.cnblogs.com/tianshug/p/10922059.html
Copyright © 2020-2023  润新知