1. 什么是单例模式?
基于某种方式是实例化多次得到的实例是同一个.
2. 为何用单例模式?
当实例化多次得到的对象中存放的属性都是一样的情况, 应该将多个对象指向同一个内存, 即同一个实例. 节省内存.
单例模式有三种实现方式, 下面一一讲述.
单例模式实现方式一: 在类中通过 if 判断, 如果实例化过就直接返回之前实例化的对象, 不会再去产生一个内存空间
- import settings
- class Mysql:
- __instance=None
- def __init__(self,ip,port):
- self.ip=ip
- self.port=port
- print(self)
- @classmethod
- def from_conf(cls): # 类作为参数自动传入 cls = Mysql
- if cls.__instance is None: # Mysql.__instance 初始为 None
- cls.__instance=cls(settings.IP,settings.PORT) # Mysql(IP,PORT)
- print(cls.__instance) # 实例化过一次就不会再去执行 if 下的语句了, 直接 return cls.__instance
- return cls.__instance # 不是空的直接返回, 可以保证返回的是同一个实例
- # obj=Mysql('1.1.1.10',3306)
- obj1=Mysql.from_conf()
- obj2=Mysql.from_conf()
- obj3=Mysql.from_conf()
- print(obj1)
- print(obj2)
- print(obj3)
- obj4=Mysql('10.10.10.11',3307)
单例模式实现方式二: 通过在类上加装饰器的方法实现. 装饰器里的 wrapper 就是 Mysql, 调用 wrapper 相当于通过 Mysql 往里面传值, 如果不传值 args 和 kwargs 长度为 0, 可以以此为关键进行判断.
- import settings
- def singleton(cls):
- cls.__instance=cls(settings.IP,settings.PORT) # 去 Mysql 中初始化对象的属性, 得到一个对象.
- def wrapper(*args,**kwargs): # wrapper 就是 Mysql
- if len(args) == 0 and len(kwargs) == 0:
- return cls.__instance # 如果 Mysql 不传值, args 和 kwargs 就是 0, 直接返回 cls.__instance
- return cls(*args,**kwargs) # 如果传值, 就执行 cls(*args,**kwargs)
- return wrapper
- @singleton #Mysql=singleton(Mysql) #Mysql=wrapper
- class Mysql:
- def __init__(self,ip,port):
- self.ip=ip
- self.port=port
- obj1=Mysql() #wrapper()
- obj2=Mysql() #wrapper()
- obj3=Mysql() #wrapper()
- print(obj1 is obj2 is obj3)
- print(obj1)
- print(obj2)
- print(obj3)
- obj4=Mysql('1.1.1.4',3308)
- print(obj4)
单例模式实现方式三:
- import settings
- class Mymeta(type):
- def __init__(self,class_name,class_bases,class_dic): #self=Mysql
- super(Mymeta,self).__init__(class_name,class_bases,class_dic )
- self.__instance=self.__new__(self) #造出一个 Mysql 的对象
- self.__init__(self.__instance,settings.IP,settings.PORT) #从配置文件中加载配置完成 Mysql 对象的初始化
- print(self.__instance)
- print(self.__instance.__dict__)
- def __call__(self, *args, **kwargs): #self=Mysql
- if len(args) == 0 and len(kwargs) == 0:
- return self.__instance
- obj=self.__new__(self)
- self.__init__(obj,*args,**kwargs)
- return obj
- class Mysql(object,metaclass=Mymeta): #Mysql=Mymeta(...)
- def __init__(self,ip,port):
- self.ip=ip
- self.port=port
- obj1=Mysql()
- obj2=Mysql()
- obj3=Mysql()
- obj4=Mysql('10.10.10.11',3308)
- print(obj1)
- print(obj2)
- print(obj3)
- print(obj4)
来源: http://www.bubuko.com/infodetail-2668453.html