1.什么叫单列模式?
首先说一下,我们操作window系统时最常用的可视化单列模式的案列 应该就是 “任务管理器”;
我们第一次打开任务管理器后(不关闭的情况下),不管我们再次打开多少次任务管理器,实际进入的还是第一次打开未关闭的任务管理器。
当然也有其他例子:
Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
单例模式提供了一个类只有一个特定类型的对象的机制。
优点:
1.在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。
2.避免对资源的多重占用(比如写文件操作)。
缺点:
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
2.实现单列模式的设计
2.1 使用模块导入的方式
Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:
首先创建demo.py 代码如下:
classTest(object):deftestSingleton(self):passobj= Test()
用模块导入的方法直接导入obj这对象
from demo importobj
a=obj
b=objprint(a)print(b)
输出结果:
2.2 基于__new__魔术方法实现(推荐此方法,方便)
classTest(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)returncls.instance#把上面的代码理解为一个固定公式就行!实现单列模式的公式!
obj1=Test()
obj2=Test()print(obj1)print(obj2)
输出结果:<__main__.test object at>
2.3 使用类
classSingleton(object):
@classmethoddef get_instance(cls, *args, **kwargs):#利用反射,看看这个类有没有instance属性
if not hasattr(Singleton, 'instance'):
Singleton.instance= Singleton(*args, **kwargs)returnSingleton.instance
s1= Singleton() #使用这种方式创建实例的时候,并不能保证单例
s2 = Singleton() #只有使用这种方式创建的时候才可以实现单例
s3 =Singleton.get_instance()
s4=Singleton.get_instance()print(s1)print(s2)print(s3)print(s4)
其实还有其他方法实现,但是我们只要熟练掌握两三种,就基本够用了,对初学者而言。