单例模式介绍:
单例模式是一种常用的软件设计模型,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。例如访问数据库、MQ等
以下有3种方法可以实现单例模式
1、模块导入:实例化一个对象后,使用的时候直接用import导入这个对象
2、通过__new__魔术方法实现:当实例化一个对象时,是先执行类的__new__方法,再执行__init__对对象进行初始化
3、通过装饰器
单例模式代码实现
1、模块导入
singleton.py:创建一个类,然后直接实例化对象
class A(): def __init__(self,name): self.name = name print(f'{self.name}实例化结束') a = A('Linda')
在其他如果需要调用这个实例化对象,可以使用from singleton import a进行导入,如果需要创建多个可以使用as进行重命名
from singleton import a as a1 from singleton import a as a2 #方法一:模块导入,实例化一个对象后,使用的时候直接用import导入这个对象 print(a1) print(a2)
打印如下:
Linda实例化结束 <singleton.A object at 0x000001B17B5208C8> <singleton.A object at 0x000001B17B5208C8>
可以看到a1和a2所指向的内存地址是一致,代表它们是同一个实例化对象
2、__new__魔术方法实现
#方法二:通过__new__魔术方法实现:当实例化一个对象时,是先执行类的__new__方法,再执行__init__对对象进行初始化 class Demo2(): #设置一个类属性来判断这个类是否实例化对象 instance = None def __new__(cls, *args, **kwargs): if cls.instance == None: #如果没有创建过对象就新创建一个并返回 cls.instance = object.__new__(cls) return cls.instance else: #创建过就直接返回创建的对象 return cls.instance D2_1 = Demo2() D2_2 = Demo2() print(D2_1) print(D2_2)
打印如下:
<__main__.Demo2 object at 0x000001B17B520408> <__main__.Demo2 object at 0x000001B17B520408>
内存地址一致,证明两次实例化创建的对象是同一个
3、装饰器
#方法三:通过装饰器 def Single_Class(cls): #用一个字典来存储类对象 instance = {} @wraps(cls) def single(*args,**kwargs): if cls not in instance: #如果类没有创建过实例对象,那就直接创建,并保存到字典中 instance[cls] = cls(*args,**kwargs) return instance[cls] else: return instance[cls] return single @Single_Class class Dmoe3(): pass #Dmoe3 = Dmoe3.__wrapped__ t1 = Dmoe3() t2 = Dmoe3() t3 = Dmoe3() print(t1) print(t2) print(t3)
输出如下:
<__main__.Dmoe3 object at 0x0000021C44B305C8> <__main__.Dmoe3 object at 0x0000021C44B305C8> <__main__.Dmoe3 object at 0x0000021C44B305C8>
可以看到t1,t2,t3的内存地址指向也都一致
装饰器扩展:
装饰器是Python中非常有特色的语法,用一个函数去装饰另一个函数或类,为其添加额外的能力。通常通过装饰来实现的功能都属横切关注功能,也就是跟正常的业务逻辑没有必然联系,可以动态添加或移除的功能。装饰器可以为代码提供缓存、代理、上下文环境等服务,它是对设计模式中代理模式的践行。在写装饰器的时候,带装饰功能的函数(上面代码中的wrapper函数)通常都会用functools模块中的wraps再加以装饰,这个装饰器最重要的作用是给被装饰的类或函数动态添加一个__wrapped__属性,这个属性会将被装饰之前的类或函数保留下来,这样在我们不需要装饰功能的时候,可以通过它来取消装饰器
例子:__wrapped__取消装饰器功能,在实例化前,执行Dmoe3 = Dmoe3.__wrapped__即可取消装饰器的功能
Dmoe3 = Dmoe3.__wrapped__ t1 = Dmoe3() t2 = Dmoe3() t3 = Dmoe3()
输出:
<__main__.Dmoe3 object at 0x000002344AAC0608> <__main__.Dmoe3 object at 0x000002344AAC0688> <__main__.Dmoe3 object at 0x000002344AAC0588>
t1,t2,t3实例化对象所指向的内存地址都不一致,是3个不同的实例化对象
单例模式的优点:
1.节约内存,因为不管实例化多少个 对象都实际指向一个内存地址;
2.多个地方创建的实例他们的属性互动,如下例子:我们只给实例化对象t1添加了一个name属性,而t2和t3都拥有了这个属性,这就给我们节约了很多的时间;
t1 = Dmoe3() t2 = Dmoe3() t3 = Dmoe3() print(t1) print(t2) print(t3) t1.name = 'linda' print(t1.name) print(t2.name) print(t3.name)
输出:
<__main__.Dmoe3 object at 0x000001BDE71205C8> <__main__.Dmoe3 object at 0x000001BDE71205C8> <__main__.Dmoe3 object at 0x000001BDE71205C8> linda linda linda
参考:https://blog.csdn.net/weixin_48636525/article/details/121355369
标签:__,Python,模式,对象,实例,Dmoe3,单例,print,cls From: https://www.cnblogs.com/trystudy/p/16719808.html