每种语言都有各自的单例模式,比如JAVA经典的懒汉,饿汉模式,或是double-check线程安全的单例模式等等。这里讲述两个比较好用的单例的python写法。
如果对__new__不熟悉的,可以参考文章《详解Python中的__init__和__new__》,简言之,__new__是一个类静态方法,创建这个类实例的方法,而__init__是在类实例创建之后调用。所以这种单例方法与经典的类似。代码如下:
# -*- coding: utf-8 -*- class Singleton(object): #重写 __new__方法 def __new__(cls, *args): if not hasattr(cls, '_instance'): #是否存在__instance变量 cls._instance = super(Singleton, cls).__new__(cls, *args) # 如果不存在,则新建一个类实例 return cls._instance @classmethod def get_instance(cls, *args): return cls.__new__(cls, *args) class MyClass(Singleton): #如果想要令MyClass变为实例,则需继承即可 pass if __name__ == '__main__': one = MyClass.get_instance() two = MyClass.get_instance() print str(one == two)
# -*- coding: utf-8 -*- from functools import wraps def singleton(cls, *args, **kw): #装饰器函数 instances = {} # 所有的单例的实例都在这个instances字典中 @wraps(cls) def _singleton(): if cls not in instances: # 当cls不在instances中 instances[cls] = cls(*args, **kw) # 则新建一个实例 return instances[cls] # 然后从instances中取 return _singleton @singleton class MyClass2(object): # 如果想要令MyClass2变为实例,则需在该类写上 “@singleton”即可,更加读者一看就明了此类是一个实例类 def __init__(self): #只有 cls不在instances中,才会调用此__init__方法 pass if __name__ == '__main__': one = MyClass2() two = MyClass2() print str(one == two)