单例模式
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保一个类只有一个实例对象。
单例模式只生成一个实例对象,减少了对系统资源的开销,当一个对象的产生需要较多的资源,如读取配置文件、产生其他依赖时,可以产生一个“单例对象”然后永久驻留内存中,从而极大降低开销。
单例模式的应用场景
在资源共享的情况下,避免由于资源操作时导致的性能或损耗等。例如日志文件,应用配置。
在控制资源的情况下,方便资源之间的互相通信。例如线程池等。
单例模式的应用实例包括:a.网站的计数器;b.应用配置;c.多线程池;d.数据库配置,数据库连接池;e.应用程序的日志应用等。
单例模式的实现
基于__new__方法实现
当实例化一个对象时,是先执行类的__new__方法(如果没有重写这个方法,那么会默认调用object.
new
)来实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,可以基于这个原理实现单例模式。
```python
class MySingleton:
__obj = None # 类属性
def __new__(cls, *args, **kwargs):
if cls.__obj == None:
print('new...')
cls.__obj = object.__new__(cls)
return cls.__obj
def __init__(self,name):
print('init...')
self.name = name
a = MySingleton("euansu")
b = MySingleton("nange")
print(a)
print(b)
print(a.name)
print(b.name)
通过如上方法生成的单例对象还存在问题,这里简单输出打印一下结果。
new…
init…
init…
<
main
.MySingleton object at 0x00000144B0F452B0>
<
main
.MySingleton object at 0x00000144B0F452B0>
nange
nange
不难发现,如上的代码在执行的时候进行了一次实例化和两次初始化,这不是我们所希望的,所以需要进行一个简单的判断,如果对象已经完成了初始化,就不再进行初始化过程。
class MySingleton:
__obj = None # 类属性
__init_flag = True # 判断实例对象是否进行过初始化
def __new__(cls, *args, **kwargs):
if cls.__obj == None:
print('new...')
cls.__obj = object.__new__(cls)
return cls.__obj
def __init__(self,name):
if self.__init_flag==True:
print('init...')
self.name = name
self.__init_flag = False
a = MySingleton("euansu")
b = MySingleton("nange")
print(a)
print(b)
print(a.name)
print(b.name)
再次执行代码,得到如下运行结果。
new…
init…
<
main
.MySingleton object at 0x00000275BD1B52B0>
<
main
.MySingleton object at 0x00000275BD1B52B0>
euansu
euansu
进行了一次实例化和一次初始化。
使用模块
编写一个模块MySingleton.py文件,代码如下:
class Singleton:
def __init__(self,name):
print("init...")
self.name = name
singleton = Singleton("euansu")
如上,生成了一个类的对象。在其他文件中导入此文件中的对象,这个对象即是单例模式的对象。
from MySingleton import singleton
print(singleton)
print(singleton.name)
执行代码,得到如下结果:
init…
euansu
使用装饰器
def Singleton(cls):
instance={}
def getsingleton(*args,**kwargs):
if cls not in instance:
instance[cls]=cls(*args,**kwargs)
return instance[cls]
return getsingleton
@Singleton
class A(object):
a = 1
def __init__(self,name):
self.name = name
def __str__(self):
return self.name
a = A("euansu")
b = A("nange")
print(a)
print(b)
运行代码,得到如下结果:
euansu
euansu