单例模式
一、什么是单例
即单个实例,指的是同一个类实例化多次的结果指向同一个对象,用于节省内存空间
如果我们从配置文件中读取配置来进行实例化,在配置相同的情况下,就没必要重复产生对象浪费内存了
# settings.py文件 IP = '1.1.1.1' PORT = 3303
二、四种单例模式的实现方式
# 方式一:定义一个类方法实现单例模式 import settings class People: __instance = None #用于保存实例化的状态 def __init__(self, ip, port): self.ip = ip self.port = port @classmethod def get(cls): if cls.__instance is None: cls.__instance = cls(settings.IP, settings.PORT) return cls.__instance obj1 = People.get() obj2 = People.get() print(obj1) print(obj2) # <__main__.People object at 0x00000000021BA9B0> # <__main__.People object at 0x00000000021BA9B0> #方式二:定义一个装饰器实现单例模式 import settings def singlet(cls): _instance = cls(settings.IP, settings.PORT) #先实例化一个对象 def wrapper(*args, **kwargs): if args or kwargs: obj = cls(*args, **kwargs) return obj #有参数是返回后来实例化对象 return _instance #无参时,返回已经实例化好的对象 return wrapper @singlet # MySQL=wrapper(MySQL) class MySQL: def __init__(self, ip, port): self.ip = ip self.port = port # 没有参数时,单例模式 obj1 = MySQL() obj2 = MySQL() obj3 = MySQL() obj4 = MySQL('1.1.1.1', 3303) print(obj1) print(obj2) print(obj3) print(obj4) # <__main__.MySQL object at 0x0000000001E6AA90> # <__main__.MySQL object at 0x0000000001E6AA90> # <__main__.MySQL object at 0x0000000001E6AA90> # <__main__.MySQL object at 0x0000000001E6AB00> #方式三:定制元类实现单例模式 import settings class Mymeta(type): def __init__(self, class_name, class_bases, class_dic): instance = self(settings.IP, settings.PORT) self.__instance = instance def __call__(self, *args, **kwargs): # self=MySQL if args or kwargs: # 有参数执行下面的代码 obj = self.__new__(self) #创造一个空对象 self.__init__(obj, *args, **kwargs) #初始化 return obj #返回对象 return self.__instance class MySQL(metaclass=Mymeta): def __init__(self, ip, port): self.ip = ip self.port = port obj1 = MySQL() obj2 = MySQL() obj3 = MySQL() obj4 = MySQL('1.2.3.1', 3305) print(obj1) print(obj2) print(obj3) print(obj4) # <__main__.MySQL object at 0x00000000021BAA90> # <__main__.MySQL object at 0x00000000021BAA90> # <__main__.MySQL object at 0x00000000021BAA90> # <__main__.MySQL object at 0x00000000021BAB00> 方式四:利用模块导入实现单例模式 # singleton模块 import settings class MySQL: def __init__(self, ip, port): self.ip = ip self.port = port instance = MySQL(settings.IP, settings.PORT) #单例模块 def f1(): from singleton import instance print(instance) def f2(): from singleton import instance, MySQL print(instance) obj = MySQL('1111', 3302) print(obj) f1() f2() # <singleton.MySQL object at 0x00000000021FAA90> # <singleton.MySQL object at 0x00000000021FAA90> # <singleton.MySQL object at 0x00000000021FA358>