目录
单例模式
一、什么是单例模式
类的设计模式有23种
单例模式是其中一种设计模式
单例模式:即单个实例,指的是同一个类实例化多次的结果都指向同一个对象,可以用于节省内存空间
二、实现单例模式的四种方法
举例:当用户输入端口和地址,实例化产生新对象
当用户不输入端口和地址,每次拿到的对象都是同一个
需要创建一个settings文件配置端口和地址数据
2.1 定义一个类方法实现单例模式
class Sql(): _instance = None def __init__(self,post,host): self.post = post self.host = host # @classmethod # def get_sigoleton(cls): # import settings # if cls._instance: # return cls._instance # else: # cls._instance=cls(settings.PORT,settings.HOST) # return cls._instance # 下面这种和上面一样,判断对象是否为空,空的就实例化产生对象 @classmethod def get_sigonleton(cls): import settings if not cls._instance: cls._instance = cls(settings.POST,settings.HOST) return cls._instance s1=Sql.get_sigonleton() s2=Sql.get_sigonleton() print(s1) print(s2)
2.2 定义一个装饰器实现单例模式
# 先定义一个装饰器 def get_sigonleton(cls): import settings _instance = cls(settings.PORT,settings.HOST) def wrapper(*args,**kwargs): if len(args) != 0 or len(kwargs) != 0: # 表示传了参数,生成新对象 res = cls(*args,**kwargs) return res else: return _instance return wrapper @get_sigonleton class Sql(): def __init__(self,port,host): self.port = port self.host = host s1=Sql() s2=Sql() print(s1) # <__main__.Sql object at 0x0000026A68DB9390> print(s2) # <__main__.Sql object at 0x0000026A68DB9390> 两个对象都指向同一个内存地址 s3=Sql(3308,'192.168.1.3') print(s3) # <__main__.Sql object at 0x0000026A68BFCE48> 用户输入数据就得到新对象
2.3 定义一个元类实现单例模式
class Mymeta(type): def __init__(self,name,bases,dic): import settings # 把实例化好的对象,放到了类的名称空间 self._instance = self(settings.PORT,settings.HOST) def __call__(self, *args, **kwargs): # 2、进行判断 if len(args) != 0 or len(kwargs) != 0: obj = object.__new__(self) obj.__init__(*args, **kwargs) return obj else: return self._instance class Sql(metaclass=Mymeta): # 相当于Sql=Mymeta(name,bases,dic),这个会调用Mymeta的__init__方法 def __init__(self,port,host): self.port = port self.host = host s1 = Sql() # 1、调用元类的__call__ s2 = Sql() print(s1) print(s2)
2.4 通过模块导入实现单例模式(python的模块是天然的单例)
# 这个方法需要先创建一个sigonleton.py文件,把类Sql的定义和实例化放到这个文件中 # 然后在本文件导入sigonleton.py中的s1 def test(): from sigonleton import s1 print(s1) def test2(): from sigonleton import s1 print(s1) test() test2()