單例模式是一種常用的軟件設計模式。在它的核心結構中只包含一個被稱為單例類的特殊類。通過單例模式可以保證系統(tǒng)中一個類只有一個實例而且該實例易于外界訪問,從而方便對實例個數(shù)的控制并節(jié)約系統(tǒng)資源。如果希望在系統(tǒng)中某個類的對象只能存在一個,單例模式是最好的解決方案。
__new__()在__init__()之前被調用,用于生成實例對象。利用這個方法和類的屬性的特點可以實現(xiàn)設計模式的單例模式。單例模式是指創(chuàng)建唯一對象,單例模式設計的類只能實例化一次。
In [15]: class Singleton:
...: def __new__(cls, *args, **kwargs):
...: if not hasattr(cls, '_instance'):
...: cls._instance = super().__new__(cls, *args, **kwargs)
...: return cls._instance
...:
In [16]: class MyClass(Singleton):
...: a = 1
...:
In [17]: my_class1 = MyClass()
In [18]: my_class2 = MyClass()
In [19]:
In [19]: my_class1.a
Out[19]: 1
In [20]: my_class2.a
Out[20]: 1
In [21]: my_class1 is my_class2
Out[21]: True
上面使用__new__來實現(xiàn)單例,下面我們使用元類來實現(xiàn)以下。
import threading
import traceback
class SingletonMetaclass(type):
def __init__(cls, name, bases, attrs):
cls._instance = None
cls._lock = threading.Lock()
def __call__(cls, *args, **kwargs):
result = None
cls._lock.acquire()
try:
if cls._instance is not None:
result = cls._instance
else:
result = cls._instance = super().__call__(*args, **kwargs)
except BaseException:
traceback.print_exc()
finally:
cls._lock.release()
return result
class Singleton(metaclass=SingletonMetaclass):
pass
In [23]: class MyClass(Singleton):
...: a = 1
...:
In [24]: my_class1 = MyClass()
In [25]: my_class2 = MyClass()
In [26]: my_class1.a
Out[26]: 1
In [27]: my_class2.a
Out[27]: 1
In [28]:
In [28]: my_class1 is my_class2
Out[28]: True
參考文章:
深刻理解Python中的元類(metaclass)以及元類實現(xiàn)單例模式
深入理解Python中的元類(metaclass)