单例(Singleton)是一种非常常见的设计模式,通过单例模式应该达到:
- 一个类只能有一个实例
- 该实例可被访问
Python所具备的动态语言的特性,让单例的实现有了多种思路:
- 从
__new__
入手__new__
是python中类的实力创建方法,它返回一个类来供__init__
进行类的初始化
class Singleton(object):
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig = super(Singleton, cls)
cls._instance = orig.__new__(cls, *args, **kw)
return cls._instance
针对可能存在的并发情况,可以加上经典的双检查锁机制
class Singleton(object):
objs = {}
objs_mutex = threading.Lock()
def __new__(cls, *args, **kwargs):
if cls in cls.objs:
return cls.objs[cls]
cls.objs_mutex.acquire()
try:
if cls in cls.objs:
return cls.objs[cls]
cls.objs[cls] = object.__new__(cls)
finally:
cls.objs_mutex.release()
- Borg模式(也叫Monostate模式)
即创建实例时把所有实例的__dict__
指向同一个字典,这样虽然并非严格的单例(实际上创造了多个实例),但每个实例所表现出来状态(属性)和行为(方法)都是一致的。
class Borg(object):
_state = {}
def __new__(cls, *args, **kw):
ob = super(Borg, cls).__new__(cls, *args, **kw)
ob.__dict__ = cls._state
return ob
- 装饰器实现 利用装饰器的变量空间来存储已经发生过实例化的对象,当其再次发生实例化的时候直接将之前的实例返回
def Singleton(cls, *args, **kw):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return getinstance
...
@Singleton
- import方法
模块实现有着诸多的好处: - 所有变量都在模块的命名空间中
- 模块只会初始化一次
- import是串行的,天然具备线程安全
# singleton.py
class Singleton(object):
def foo(self):
pass
my_singleton = My_Singleton()
# main.py
from mysingleton import my_singleton
...
```