zoukankan      html  css  js  c++  java
  • 单例

    引子

    基于元类实现单例模式
    单例:即单个实例,指的是同一个类实例化多次的结果指向同一个对象,用于节省空间
    场景:假若从配置文件中读取配置来进行实例化,在配置相同的情况下,就没必要重复产生对象浪费内存了)

     至少会用三种方式创建。

    # 方式一:定义一个类方法实现单例模式
     1 # 方式一:定义一个类方法实现单例模式
     2 import setting
     3 
     4 class Mysql:
     5     instance = None
     6     def __init__(self,host,port):
     7         self.host = host
     8         self.port = port
     9 
    10     @classmethod
    11     def from_conf(self):
    12         if not Mysql.instance:
    13             res = Mysql(setting.HOST, setting.PORT)
    14             Mysql.instance = res
    15         return Mysql.instance
    16 
    17 # con1 = Mysql('127.0.0.1',80) # <__main__.Mysql object at 0x000000A9F7FC7978>
    18 # con2 = Mysql('127.0.0.1',80) # <__main__.Mysql object at 0x000000A9F7FD8710>
    19 # con3 = Mysql('127.0.0.1',80) # <__main__.Mysql object at 0x000000A9F7E09C88>
    20 # print(con1,con2,con3)
    21 #
    22 
    23 # con1 = Mysql.from_conf() # <__main__.Mysql object at 0x000000BB72BA4DD8>
    24 # con2 = Mysql.from_conf() # <__main__.Mysql object at 0x000000BB72BA4E48>
    25 # con3 = Mysql.from_conf() # <__main__.Mysql object at 0x000000BB72BA4E80>
    26 # print(con1,con2,con3)
    27 
    28 con1 = Mysql.from_conf() # <__main__.Mysql object at 0x000000BD5BBA4DD8>
    29 con2 = Mysql.from_conf() # <__main__.Mysql object at 0x000000BD5BBA4DD8>
    30 con3 = Mysql.from_conf() # <__main__.Mysql object at 0x000000BD5BBA4DD8>
    31 print(con1 is con2 is con3) # True
    类方法实现单例
    # 方式二:定义元类实现
    若从配置文件取相同配置产生对象则实现单例,若传值则新建对象
     1 # 方式二:定制元类实现
     2 # 若从配置文件取相同配置产生对象则实现单例,若传值则新建对象
     3 import setting
     4 
     5 class Mymeta(type):
     6     def __init__(self,name,bases,dic): # 定义类Mysql时就触发
     7 
     8         # 事先从配置文件中取配置来造一个Mysql的实例出来
     9         self.__instance = object.__new__(self) # 产生对象
    10         self.__init__(self.__instance,setting.HOST,setting.PORT) # 初始化对象
    11         #上述两步可合并下面一步
    12         # self.__instance = super().__call__(*args,**kwargs)
    13 
    14         super().__init__(name,bases,dic)
    15 
    16     def __call__(self, *args, **kwargs): # Mysql(...)时触发
    17         if args or kwargs: # Mymeta类的对象括号内传值则新建obj,否则返回self.__instance
    18             obj = object.__new__(self)
    19             self.__init__(obj,*args,**kwargs)
    20             return obj
    21         return self.__instance
    22 
    23 
    24 # Mysql = Mymeta('Mysql',(obj,),class_dic)
    25 class Mysql(metaclass=Mymeta):
    26     def __init__(self,host,port):
    27         self.host = host
    28         self.port = port
    29 
    30 con1 = Mysql()
    31 con2 = Mysql()
    32 con3 = Mysql() # <__main__.Mysql object at 0x0000008BA7E24DD8>
    33 con4 = Mysql('127.0.0.1',80) # <__main__.Mysql object at 0x0000004B4B904EF0>,若Mymeta类的对象(Mysql)括号内传值则新建obj
    34 print(con4) # True
    元类实现单例
    # 方式三:装饰器实现
     1 import setting
     2 
     3 def single_obj(cls):
     4     __instance = cls(setting.HOST,setting.PORT)
     5     def wrapper(*args, **kwargs):
     6         if args or kwargs:
     7             obj = cls(*args, **kwargs)
     8             return obj
     9         return __instance
    10     return wrapper
    11 
    12 @single_obj
    13 class Mysql:
    14     def __init__(self,host,port):
    15         self.host = host
    16         self.port = port
    17 
    18 con1 = Mysql() # <__main__.Mysql object at 0x0000001F978D9C88>
    19 con2 = Mysql() # <__main__.Mysql object at 0x0000001F978D9C88>
    20 con3 = Mysql('127.0.0.1',80) # <__main__.Mysql object at 0x0000001F98AE4DD8>
    21 
    22 print(con1 is con2) # True
    装饰器实现单例
  • 相关阅读:
    Python-爬取小说内容并下载
    Python-网易音乐下载
    [Python图像处理]六.图像缩放,图像旋转,图像翻转与图像平移
    [Python图像处理]五.图像加法运算,图像融合及图像类型转换
    [Python图像处理]四.图像平滑中四种常用的滤波
    go语言-从控制套获取用户输入
    go语言-运算符
    go语言-指针
    go语言-数据类型及类型之间转换
    go语言-变量与常量
  • 原文地址:https://www.cnblogs.com/limengjie0104/p/8871817.html
Copyright © 2011-2022 走看看