Python - 单列模式
1.什么叫单列模式?
首先说一下,我们操作window系统时最常用的可视化单列模式的案列 应该就是 “任务管理器”;
我们第一次打开任务管理器后(不关闭的情况下),不管我们再次打开多少次任务管理器,实际进入的还是第一次打开未关闭的任务管理器。
当然也有其他例子:
Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
单例模式提供了一个类只有一个特定类型的对象的机制。
优点:
1.在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。
2.避免对资源的多重占用(比如写文件操作)。
缺点:
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
2.实现单列模式的设计
2.1 使用模块导入的方式
Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc
文件,当第二次导入时,就会直接加载 .pyc
文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:
首先创建demo.py 代码如下:
class Test(object): def testSingleton(self): pass obj = Test()
用模块导入的方法直接导入obj这对象
from demo import obj a = obj b = obj print(a) print(b)
输出结果:<demo1.Test object at 0x00000154F3FFBB00>
<demo1.Test object at 0x00000154F3FFBB00>
2.2 基于__new__魔术方法实现(推荐此方法,方便)
class Test(object): # __new__魔术方法,类似__init__方法,比__init__方法还先执行 def __new__(cls, *args, **kwargs): # hasattr方法判断cls这个对象是否有instance这个属性,如果没有就执行if下的语句,有则跳过 # 每一个实力化后的类都会有一个instance属性,这里不用纠结“instance怎么来的,为什么会有instance”这种问题 if not hasattr(cls, 'instance'): cls.instance = super().__new__(cls) return cls.instance # 把上面的代码理解为一个固定公式就行!实现单列模式的公式! obj1 = Test() obj2 = Test() print(obj1) print(obj2)
输出结果:<__main__.Test object at 0x00000236D348BB38>
<__main__.Test object at 0x00000236D348BB38>
2.3 使用类
class Singleton(object): @classmethod def get_instance(cls, *args, **kwargs): # 利用反射,看看这个类有没有instance属性 if not hasattr(Singleton, 'instance'): Singleton.instance = Singleton(*args, **kwargs) return Singleton.instance s1 = Singleton() # 使用这种方式创建实例的时候,并不能保证单例 s2 = Singleton() # 只有使用这种方式创建的时候才可以实现单例 s3 = Singleton.get_instance() s4 = Singleton.get_instance() print(s1) print(s2) print(s3) print(s4)
其实还有其他方法实现,但是我们只要熟练掌握两三种,就基本够用了,对初学者而言。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步