单例模式是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.
单例模式的要点三个:
--某个类智能有一个实例
--他必须自行创建这个实例
--必须自行向整个系统提供这个实例
在python中,我们可以用多种方法来实现单例模式:
使用模块
使用__new__
使用装饰器(decorator)
使用元类(metaclass)
使用模块
python的模块就是天然的单例模式
classMyclass(object):deffoo(self):print('Myclass.foo')
my_class_obj=Myclass()
fx.py
from fx importmy_class_obj
my_class_obj.foo()
使用__new__
classMyclass(object):
_instance=Nonedef __new__(cls, *args, **kwargs):if notcls._instance:
cls._instance=super(Myclass, cls).__new__(cls,*args,**kwargs)returncls._instance#我们将类的实例和一个类变量_instance关联起来,如果cls._instance为None则创建实例,否者直接返回cls._instance
classHerclass(Myclass):
a=1one=Herclass()
two=Herclass()print(one==two)print(one istwo)print(id(one),id(two))
__new__
使用装饰器
from functools importwrapsdefsin(cls):
instances={}
@wraps(cls)def get(*args,**kwargs):if cls not ininstances:
instances[cls]=cls(*args,**kwargs)returninstances[cls]
@sinclassMyclass(object):
a=1
#我们定义了一个装饰器sin,他返回了一个内部函数get,该函数会判断某一个类是否在字典instance中,如果不存在,就会将cls#作为key,cls(*args, **kw) 作为 value 存到 instances 中,否则,直接返回 instances[cls]。
装饰器
使用__metaclass__
元类可以控制类的创建过程,三件事:
---拦截类的创建
---修改类的定义
---返回修改后的类
importthreadingclassSingleton2(type):def __init__(cls, name, bases, dict):
super(Singleton2, cls).__init__(name, bases, dict)
cls._instance=Nonedef __call__(cls, *args, **kw):if cls._instance isNone:
cls._instance= super(Singleton2, cls).__call__(*args, **kw)returncls._instance#python2
classMyClass(object):__metaclass__ =Singleton2
one=MyClass()
two=MyClass()
two.a= 3
#print one.a#3#print id(one)#31495472#print id(two)#31495472
__metaclass__