单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此有些设计大师把其称为设计模式之一
单例模式保证了在程序的不同位置都可以且仅可以取到同一个对象的实例,如果实例不存在,会创建一个实例;否则返回这个实例。单例是一个类,可以为其提供相应的操作方法,便于管理,节约内存资源。
应用场景:
windows的任务管理器,只能打开一个;
网站的计数器,一般采用单例模式实现,否则难以同步;
多线程的线程池,便于对线程的控制;
应用程序的日志应用,一般是用单例模式,是由于共享的日志文件一直处于打开状态,只能有一个实例去操作;
。。。。。。
单例模式实现方法:
装饰器实现单例模式:
def singleton(cls):
_instance = {}
def inner(*args,**kwargs):
if cls not in _instance:
_instance[cls] = cls(*args,**kwargs)
return _instance[cls]
return inner
@singleton
class Examples(object):
def __init__(self,*args,**kwargs):
pass
examples1 = Examples()
examples2 = Examples()
print(id(examples1) == id(examples2))
#结果:
#True
@singleton
class Examples1(object):
def __init__(self,*args,**kwargs):
pass
examples3 = Examples1()
print(id(examples1) == id(examples3))
#结果:
#False
通过打印结果可知,第一次打印结果是True,说明它们指向了同一个对象,第二次打印结果是False;
当第一次调用这个类时,会将类地址作为键保存在_instance中,值为实例;每次创造实例时,会先看该类是否存在,存在直接返回即可,否则新建一个实例并存放到_instance中,将实例返回;
__new__实现单例模式:
class Singleton(object):
__instance = None
def __new__(cls,*args,**kwargs):
if not cls.__instance:
cls.__instance = object.__new__(cls)
return cls.__instance
single1 = Singleton()
single2 = Singleton()
print(id(single1) == id(single2))
#结果:
#True
_instance存放实例,有责返回实例,无则创建实例保存并返回
模块方式单例模式
python的模块是天然的单例模式,因为模块在第一次导入时,会生成 .pyc
文件,当第二次导入时,就会直接加载 .pyc
文件,而不会再次执行模块代码。
因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:
#sinton.py
class Singleton1(object):
def foo(self):
pass
mysinton = Singleton1()
在其他文件中运用方法:
from sinton import mysinton
mysinton.foo()
基于metaclass实现单例模式
先了解下type创造类的方法
def func(self):
print("do sth")
Singleton = type("Singleton", (), {"func": func})
c = Singleton()
c.func()
以上就是使用type创造的一个类,这是metaclass实现单例模式的基础
单例模式如下
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class Cls4(metaclass=Singleton):
pass
cls1 = Cls4()
cls2 = Cls4()
print(id(cls1 ) == id(cls2))
#结果:
#True
这里,我们将 metaclass 指向 Singleton 类,让 Singleton 中的 type 来创造新的 Cls4 实例
以上就是几种方式实现的单例模式,还有一些其他的实现方式,可以自行百度了解下;