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