单例模式的三种实现⽅式
⼀、单例模式的三种实现⽅式
单例模式的几种实现方式
1. 什么是单例模式
基于某种⽅法,实例化多次,得到同⼀个实例/对象
2. 为什么⽤单例模式
实例化多次,得到的对象属性内容都⼀样时,应该将这些对象指向同⼀个内存,即同⼀个实例,来节省内存空间1. 实现单例模式⽅式⼀:类内部定义类⽅法实现
实现⽅法:类中定义了⼀个类⽅法
# 未单例模式前
import setting
class Mysql:
def __init__(self,ip,port):
self.ip=ip
self.port=port
@classmethod
def from_conf(cls):
return cls(setting.IP,setting.PORT)
obj1=Mysql.from_conf()
obj2=Mysql.from_conf()
obj3=Mysql.from_conf()
# 内容相同
print(obj1.__dict__)
print(obj2.__dict__)
print(obj3.__dict__)
# 但是占⽤不同的内存空间,导致内存空间浪费
print(obj1)
print(obj2)
print(obj3)
----------------------------------------------------
{'ip': '10.0.0.1', 'port': 3306}
{'ip': '10.0.0.1', 'port': 3306}
{'ip': '10.0.0.1', 'port': 3306}
<__main__.Mysql object at 0x000001B0F234F588>
<__main__.Mysql object at 0x000001B0F234F5F8>
<__main__.Mysql object at 0x000001B0F234F630>
# setting配置⽂件
IP='10.0.0.1'
PORT=3306
import setting
class Mysql:
# 先定义⼀个变量,⽤于接收对象
__instance=None
def __init__(self,ip,port):
self.ip=ip
self.port=port
@classmethod
def from_conf(cls):
# 如果没有实例化过,就重新实例化,如果有就返回实例化过的对象        if cls.__instance is None:
cls.__instance=cls(setting.IP,setting.PORT)
return cls.__instance
obj1=Mysql.from_conf()
obj2=Mysql.from_conf()
obj3=Mysql.from_conf()
# 内容相同
print(obj1.__dict__)
print(obj2.__dict__)
print(obj3.__dict__)
# 占⽤相同的内存空间
print(obj1)
print(obj2)
print(obj3)
---------------------------------------------------------------
{'ip': '10.0.0.1', 'port': 3306}
{'ip': '10.0.0.1', 'port': 3306}
{'ip': '10.0.0.1', 'port': 3306}
<__main__.Mysql object at 0x000001A79D29F588>
<__main__.Mysql object at 0x000001A79D29F588>
<__main__.Mysql object at 0x000001A79D29F588>
# 如果ip,port不同,再单独造对象
obj4=Mysql('10.0.0.10',3307)
print(obj4)
print(obj4.__dict__)
---------------------------------------------------------------
<__main__.Mysql object at 0x0000015D8C13F630>
{'ip': '10.0.0.10', 'port': 3307}
2. 实现单例模式⽅式⼆:利⽤装饰器实现
_intance是⼀种命名习惯,代表在函数内使⽤的名字
import setting
def singleton(cls):
_intance=cls(setting.IP,setting.PORT)
def wrapper(*args,**kwargs):
if len(args) == 0 and len(kwargs) == 0:
return _intance
return 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()
obj3=Mysql()
print(obj1 is obj2 is obj3)
print(obj1)
print(obj2)
print(obj3)
-----------------------------------------------------
True
<__main__.Mysql object at 0x000001ED9FBDF588>
<__main__.Mysql object at 0x000001ED9FBDF588>
<__main__.Mysql object at 0x000001ED9FBDF588>
3. 实现单例模式⽅式三:定制元类实现
import setting
class Mymeta(type):
def __init__(self,class_name,class_bases,class_dic): # self=Mysql        super().__init__(class_name,class_bases,class_dic)
# 创造⼀个Mysql的空对象
self.__instance=self.__new__(self)
# 从配置⽂件中获取信息,初始化Mysql的对象
self.__init__(self.__instance,setting.IP,setting.PORT)
def __call__(self, *args, **kwargs):  # self=Mysql
if len(args) == 0 and len(kwargs) == 0:
return self.__instance  # 返回的是⼀个已经创建好的Mysql对象        # 如果在Myql()括号内,单独传⼊内容,再重新造对象
obj=self.__new__(self)
self.__init__(self,*args,**kwargs)
return obj
class Mysql(object,metaclass=Mymeta):
def __init__(self,ip,port):
self.ip=ip
self.port=port
obj1=Mysql()
obj2=Mysql()
obj3=Mysql()
obj4=Mysql('10.0.0.10',3307)
print(obj1)
print(obj2)
print(obj3)
print(obj4)
--------------------------------------------------------------------------
<__main__.Mysql object at 0x0000021DBB7FF668>
<__main__.Mysql object at 0x0000021DBB7FF668>
<__main__.Mysql object at 0x0000021DBB7FF668>
<__main__.Mysql object at 0x0000021DBB7FF6A0>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。