Python:單例模式
轉載自
單例(Singleton)模式 也叫單態模式
概述:單例(Singleton)模式要求一個類有且僅有一個例項,並且提供了一個全域性的訪問點。這就提出了一個問題:如何繞過常規的構造器,提供一種機制來保證一個類只有一個例項?客戶程式在呼叫某一個類時,它是不會考慮這個類是否只能有一個例項等問題的,所以,這應該是類設計者的責任,而不是類使用者的責任。 從另一個角度來說,Singleton模式其實也是一種職責型模式。因為我們建立了一個物件,這個物件扮演了獨一無二的角色,在這個單獨的物件例項中,它集中了它所屬類的所有權力,同時它也肩負了行使這種權力的職責!
語言是共通的,想要用不同語言實現單例模式,首先要清楚什麼是單例模式,單例模式即一個類有且僅有一個例項
首先先建立一個類,比如宇宙只有一個地球
-
class Earth:
-
pass
-
a = Earth()
-
print(id(a))
-
b = Earth()
-
print(id(b))
執行結果如下:
通過列印例項的id可以發現,地球類預設建立了兩個例項。
那麼怎麼能夠讓類只建立一個例項,而後再建立的例項是返回上一次的物件的引用呢?
我們瞭解到,python中,一個類建立物件例項是通過呼叫父類object的 __new__(cls)方法來建立物件的
我們可以通過重寫 __new__(cls)方法去實現類只建立一個例項
程式碼如下:
-
class Earth(object):
-
__instance=None #定義一個類屬性做判斷
-
def __new__(cls):
-
if cls.__instance==None:
-
#如果__instance為空證明是第一次建立例項
-
#通過父類的__new__(cls)建立例項
-
cls.__instance==object.__new__(cls)
-
return cls.__instance
-
else:
-
#返回上一個物件的引用
-
return cls.__instance
-
a = Earth()
-
print(id(a))
-
b = Earth()
-
print(id(b))
執行結果如下:
可以看出它們id相同,是同一個物件。
適用場景: 1.需要生成唯一序列的環境
2.需要頻繁例項化然後銷燬的物件。
3.建立物件時耗時過多或者耗資源過多,但又經常用到的物件。
4.方便資源相互通訊的環境
優點:1.實現了對唯一例項訪問的可控
2.對於一些需要頻繁建立和銷燬的物件來說可以提高系統的效能。
缺點:1. 不適用於變化頻繁的物件
2.濫用單例將帶來一些負面問題,如為了節省資源將資料庫連線池物件設計為的單例類,可能會導致共享連線池物件的程式過多而出現連線池溢位。
3.如果例項化的物件長時間不被利用,系統會認為該物件是垃圾而被回收,這可能會導致物件狀態的丟失。
比如:回收站,我們在實際使用中並不存在需要同時開啟兩個回收站視窗的必要性。網站的計數器:
如果你存在多個計數器,每一個使用者的訪問都重新整理計數器的值,這樣的話你的實計數的值是難以同步的。但是如果採用單例模式實現就不會存在這樣的問題,而且還可以避免執行緒安全問題。同樣多執行緒的執行緒池的設計一般也是採用單例模式,這是由於執行緒池需要方便對池中的執行緒進行控制
同樣,對於一些應用程式的日誌應用,或者web開發中讀取配置檔案都適合使用單例模式,如HttpApplication 就是單例的典型應用。