標籤:war 完成 tor new 其他 .com false __init__ print
研究了一下python的單利模式,簡單地記錄一下.
1.類和執行個體的建立過程
從建立類到初始化一個對象,簡單地可以分為四個步驟:
(1)通過元類建立一個類,調用__new__完成類的建立(階段A)
(2)初始化一個類,調用__init__,初始化一個類(階段B)
(3)通過類建立一個對象,調用__new__(階段D)
(4)初始化一個對象,調用__init__(階段E)
圖中階段A,階段B,階段C是由元類完成的,在檔案載入的時候,自動調用__new__和__init__,階段E不是必須的.階段D,階段E是建立一個執行個體的過程,手動調用__new__和__init__.一般情況下,建立一個類只用執行個體化一個類,即調用__init__,而__new__的執行被隱藏了,主要是繼承了父類的__new__方法
說完了類和執行個體的建立過程之後,考慮一下單例模式應該在這四個階段中哪個階段控制比較合適?
(1)階段A:
建立一個類的過程,也就是說類的建立並未完成.單例是建立執行個體上,執行個體的建立又是建立在類上面的,這個階段類還沒有建立,也就不太適合
(2)階段B:
執行個體化一個類,這個階段類也建立完成了,似乎有機會控制執行個體的個數
(3)階段D:
類的建立和執行個體化完成了,開始建立一個執行個體,但還未完成,也可以控制執行個體的個數
(4)階段E:
這個階段,對象已經建立了,每一次執行個體化一個類時,對象已經建立了,控制不了執行個體的個數.
簡單說,階段A (建立類的過程)類沒有建立,不宜控制執行個體數量.階段E(類執行個體化的過程)執行個體已經建立,控制不了執行個體數量.在階段B(執行個體化一個類)和階段D(建立一個執行個體)比較容易控制執行個體的數量,也就最利於實現單例模式.
2.實現單例模式
(1)階段B(執行個體化一個類)
主要是通過建立元類進行控制:
# B階段class Singleton_C(type): def __init__(self, *args, **kwargs): self.__instance = None super(Singleton_C, self).__init__(*args, **kwargs) def __call__(self, *args, **kwargs): if self.__instance is None: self.__instance = super(Singleton_C, self).__call__(*args, **kwargs) return self.__instance else: return self.__instance class C: __metaclass__ = Singleton_C def __init__(self): print ‘I am C‘a = C() b = C()print a is b # True
(2)階段D(建立執行個體的過程)
# D階段class Singleton_D(object): ‘‘‘執行個體儲存在Sigleton_B類的字典中‘‘‘ def __new__(cls, *args, **kwargs): if not hasattr(cls, ‘_instance‘): cls._instance = super(Singleton_B, cls).__new__(cls, *args, **kwargs) return cls._instance # 先繼承其他類時, 會導致單例模式失效 class D(Singleton_D): def __init__(self): print ‘I am D‘a = D()b = D()print a is b # True
(3)階段D(建立執行個體的過程) --- 一個偽單例模式
每一次實現的對象不同,但共用變數
# D階段class Singleton_D1(object): _store = {} def __new__(cls, *args, **kwargs): obj = super(Singleton_B1, cls).__new__(cls, *args, **kwargs) print cls, obj, id(cls._store), id(obj._store), id(Singleton_B1._store) obj.__dict__ = cls._store return obj# 先繼承其他類時, 會導致單例模式失效 class F(Singleton_D1): def __init__(self, name): self.name = namef1 = F(‘python‘)f2 = F(‘singleton‘)print f1 is f2 # False
(4)裝飾器
def singleton(cls): obj = {} def wrapper(*args, **kwargs): if cls not in obj: obj[cls] = cls(*args, **kwargs) return obj[cls] return wrapper@singletonclass Foo(object): passf1 = Foo()f2 = Foo()print f1 is f2 # True
python 單例模式