第一阶段:Python开发基础 day30 面向对象高阶--单例模式
一、什么是单例模式
- 单例模式:基于某种方法实例化多次得到实例是同一个
二、为什么用单例模式
- 当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存,即同一个实例
三、种方式实现单例模式
-
第一种(通过类的绑定方法)
dic = {'PORT':3306,'HOST':'127.0.0.1'} class Demo1(): _instance = None def __init__(self,port,host): self.port = port self.host = host @classmethod def get_sigoleton(cls): if not cls._instance: cls._instance = cls(dic['PORT'],dic['HOST']) return cls._instance s1 = Demo1.get_sigoleton() s2 = Demo1.get_sigoleton() s3 = Demo1(33306,'192.168.1.1') print(s1) print(s2) print(s3)
-
第二种(通过装饰器)
-
用户输入端口和地址,实例化产生对象
-
当用户不输入端口和地址,每次拿到的对象,都是同一个
dic = {'PORT':3306,'HOST':'127.0.0.1'} def get_sigoleton(cls): _instance=None def wrapper(*args,**kwargs): if len(args)!=0 or len(kwargs)!=0: #表示传了参数,生成新对象 res=cls(*args,**kwargs) return res else: nonlocal _instance if not _instance: _instance=cls(dic['PORT'], dic['HOST']) return _instance return wrapper @get_sigoleton #会把下面的Sql当中参数传入,相当于:Sql=get_sigoleton(Sql) class Sql(): def __init__(self,port,host): self.port=port self.host=host s1=Sql() s2=Sql() s3=Sql('33306','192.168.1.1') s4=Sql('33306','192.168.1.1') print(s1) print(s2) print(s3)
-
-
第三种(通过元类)
- 当用户输入端口和地址,实例化产生新对象
- 当用户不输入端口和地址,每次拿到的对象,都是同一个
dicc = {'PORT':'3306','HOST':'127.0.0.1'} class Mymeta(type): def __init__(self,name,bases,dic): #self 是Sql类 #把实例化好的对象,放到了类的名称空间 self._instance=self(dicc['PORT'], dicc['HOST']) def __call__(self, *args, **kwargs): #self是谁?是Sql类 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 print(Sql.__dict__) s1=Sql() #调用元类的__call__ s2=Sql() s3=Sql('33306','192.168.1.1') print(s1) print(s2) print(s3)
-
第四种(通过模块导入:python中的模块是天然的单例)
def test(): from sigonleton import s1 print(s1.port) print(s1) def test2(): from sigonleton import s1 as s2 print(s2) test() test2() from sigonleton import s1 from sigonleton import Sql s2=Sql(3306,'192.168.1.1') print(s1) print(s2) # 被调用的 sigonleton.py文件 def test(): from sigonleton import s1 print(s1.port) print(s1) def test2(): from sigonleton import s1 as s2 print(s2) test() test2() from sigonleton import s1 from sigonleton import Sql s2=Sql(3306,'192.168.1.1') print(s1) print(s2)