模式"/>
看,python单例设计模式
要了解单例设计模式,我们首先要了解什么是设计模式。
设计模式:通俗的讲就是每一个模式都是我们在代码中不断要遇到的问题,通过分析,然后分类这些问题,进行代码的设计和经验的总结。为了就是可重用代码,让代码的设计更容易被他人理解,保证了代码的可靠性。
单例设计模式:目的就是让类创建的对象,在系统中只有唯一的实例,每一次执行类名()返回的对象,内存地址是相同的,这样就可以让软件更加的有秩序的运行,也节省了内存。
应用对场景:
回收站(在系统的运行中,回收站一直存在仅有的一个实例)
任务管理器(在系统中只能打开一个任务管理器)
Django框架中的配置文件读取,也是单例模式,因为配置文件是共享的资源
还有一些软件也是遵循这种方法音频类的软件基本上都是单例模式,在这就不一一列举了。
下面我们就以回收站做一个简单的实例:
在使用单例前我们还要理解__new__这个python的内置方法。
当我们创建一个类的时候,我们基本上用的最常用的是__init__初始化的方法,在这个方法中可以定义实例的属性。
但是在类中创建每个对象时,都要给这个对象分配空间,这个任务就交给了__new__方法
所以当我们要写单例模式的时候我们首先要对__new__方法进行重构。
下面我们先实现这个__new__方法
class Trash(object):def __new__(cls, *args, **kwargs):print("new方法被调用")def __init__(self):print('开始收集')a = Trash()
print(a)---------------------->
new方法被调用
None
通过上面的代码我们看出__new__方法中有三个参数,第一个参数就是哪个类调用就传递哪个类,现在传递的就是Trash类。
后面两个参数可以看我的这篇博客(),另外我们可以看出我们返回的结果中没有初始化的值。这是因为我们没有分配空间和返回对象的引用,只是在创建这个对象时,new的方法被自动调用了。
要怎样分配空间和返回对象引用呢?
在这我们可以调用object基类中的__new__的默认方法,它已经可以为对象分配空间。
class Trash:def __new__(cls, *args, **kwargs):print("new方法被调用")space = super().__new__(cls)return spacedef __init__(self):print('开始收集')a = Trash()
print(a)---------------------->
new方法被调用
开始收集
<__main__.Trash object at 0x00000271EDFD6BA8>
有上面我们看的出通过继承父类的new方法,便可以为a这个实例对象创建空间。
return space 由sapce接收了父类方法返回的结果,然后在返回这个变量,__new__的方法也就重构完成。这样我们就可以接受到实例中的属性。
讲到这我们也只是介绍了怎样改造__new__这个方法, 下面便会引出怎样将许多软件回收到垃圾桶里
class Trash:def __new__(cls, *args, **kwargs):print("new方法被调用")space = super().__new__(cls)return spacedef __init__(self):self.name = nameprint('卸载完成')mooc = Trash()
dingding= Trash()
xuexitong = Trash()
print(mooc,dingding,xuexitong)
---------------------->
new方法被调用
卸载完成
new方法被调用
卸载完成
new方法被调用
卸载完成
<__main__.Trash object at 0x000002B99B946BA8> <__main__.Trash object at 0x000002B99B946B70> <__main__.Trash object at 0x000002B99B946BE0>
通过上面的代码我们当我们创建三个实例对象的时候,在Trash类中每次都会创建一个新的内存。对于这类都是属于同一类的对象来说,显然这样是我们不希望的。所以我们稍微改进一下,先呈上。
class Trash:space = Nonedef __new__(cls, *args, **kwargs):if cls.space is None:print("new方法被调用")cls.space = super().__new__(cls)return cls.spacedef __init__(self):print('卸载完成')mooc = Trash()
dingding= Trash()
xuexitong = Trash()
print(mooc,dingding,xuexitong)
--------------------------->
new方法被调用
卸载完成
卸载完成
卸载完成
<__main__.Trash object at 0x0000020C7A636BA8> <__main__.Trash object at 0x0000020C7A636BA8> <__main__.Trash object at 0x0000020C7A636BA8>
在改进中,我们分析了我们所遇到的核心问题:多次调用的方法本质上还是一个对象,也就是唯一的实例。所以我们要对是否分配空间做一次判断,如果已经创建空间,那么在下次来的时候直接返回对象的引用。
-------------->引出了我们对单例的理解:在类创建对象的时候,不管你调用多少次类的方法,得到的结果永远都是内存中唯一的实例。这就是我们单例所想要达到结果。
上面我们一直都是在改造__new__的方法实现单例,下面我们也应该对初始化的方法下手改造了。
class Trash:space = Noneflag = Falsedef __new__(cls, *args, **kwargs):if cls.space is None:print("new方法被调用")cls.space = super().__new__(cls)return cls.spacedef __init__(self):if Trash.flag:returnprint('卸载完成')Trash.flag = Truemooc = Trash()
dingding= Trash()
xuexitong = Trash()
print(mooc,dingding,xuexitong)
------------------------------>
new方法被调用
卸载完成
<__main__.Trash object at 0x0000027B34966BE0> <__main__.Trash object at 0x0000027B34966BE0> <__main__.Trash object at 0x0000027B34966BE0>
我们可以定义一个类属性,当我们在创建完对象的引入后,进行判断让初始化的方法也只进行调用一次。使用单例方法,可以大大节省了程序运行的时间,减少内存,更加明确类的分工。
see you !!!
更多推荐
看,python单例设计模式
发布评论