如何實(shí)現(xiàn)Python中的單例
1.重寫Class的new方法
#__new__函數(shù)就是class在創(chuàng)建對象時會調(diào)用的方法
#通過重寫__new__函數(shù)可以控制只創(chuàng)建一個對象
#子類可以通過重寫__new__函數(shù)
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__函數(shù)
#子類除非指定別的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:
#這段代碼的作用是每次都調(diào)用class的init函數(shù)
cls._instances[cls].__init__(*args, **kwargs)
return cls._instances[cls]
#Python2
class MyClass(BaseClass):
__metaclass__ = Singleton
#Python3
class MyClass(BaseClass, metaclass=Singleton):
pass
PS:上面的寫法都沒有加線程鎖,如果考慮在多線程的環(huán)境下使用需要加線程鎖
import functools
import threading
lock = 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 wrapper
class 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
PS: 在Python中,import默認(rèn)只會導(dǎo)入一次,除非使用reload函數(shù)刷新,否則每個module只會導(dǎo)入一次,這樣的話,如果導(dǎo)入一個變量,則這個變量就相當(dāng)于單例