Python|Python Singleton

如何实现Python中的单例 1.重写Class的new方法

#__new__函数就是class在创建对象时会调用的方法 #通过重写__new__函数可以控制只创建一个对象 #子类可以通过重写__new__函数 class Singleton(object): _instance = None def __new__(class_, *args, **kwargs): if not isinstance(class_._instance, class_): class_._instance = object.__new__(class_, *args, **kwargs) return class_._instance

2.指定metaclass
#通过metaclass控制class的__new__函数 #子类除非指定别的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) else: #这段代码的作用是每次都调用class的init函数 cls._instances[cls].__init__(*args, **kwargs) return cls._instances[cls]#Python2 class MyClass(BaseClass): __metaclass__ = Singleton#Python3 class MyClass(BaseClass, metaclass=Singleton): pass

PS:上面的写法都没有加线程锁,如果考虑在多线程的环境下使用需要加线程锁
import functools import threadinglock = threading.Lock()def synchronized(lock): """ Synchronization decorator """ def wrapper(f): @functools.wraps(f) def inner_wrapper(*args, **kw): with lock: return f(*args, **kw) return inner_wrapper return wrapperclass Singleton(type): _instances = {}@synchronized(lock) 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 SingletonClass(metaclass=Singleton): pass

【Python|Python Singleton】PS: 在Python中,import默认只会导入一次,除非使用reload函数刷新,否则每个module只会导入一次,这样的话,如果导入一个变量,则这个变量就相当于单例

    推荐阅读