單例模式是一種建立型設計模式,它確保乙個類有且只有乙個特定型別的物件,並提供全域性訪問點。其意圖為:簡單理解:單例即為單個例項,也就是每次例項化建立物件時獲得的都是同乙個物件,當然同乙個物件的屬性都是相同的,方法也是相同的,位址也是相同的,這樣給我們帶來的好處就是可以避免消耗過多的記憶體或cpu資源,例如資料庫類,我們希望每次都使用同乙個資料庫物件來對資料庫進行操作,以維護資料的一致性。又如模組的匯入,如果沒有匯入該模組,則匯入該模組並例項化,如果已經匯入,則返回該模組的物件
classsingleton():def__new__(cls, *args, **kwargs):ifnothasattr(cls,'instance'):
cls.instance=super(singleton,cls).__new__(cls)returncls.instance
a=singleton()
b=singleton()
print(a)#<__main__.singleton object at 0x00000220866ef400>
print(b)#<__main__.singleton object at 0x00000220866ef400>
new方法為python例項化建立物件自動執行的函式,通過重寫這個函式,使之先判斷該類中是否有instance屬性(利用反射),若沒有則為建立乙個物件並為該屬性賦值,最後返回instance中的物件。通過這種方式我們實現了每次建立例項返回的都是類中的instance的值。
classsingleton():
__instance=nonedef__init__(self):pass@classmethoddefgetinstance(cls):ifnotcls.__instance:
cls.__instance = singleton()returncls.__instance
a=singleton.getinstance()#<__main__.singleton object at 0x000001c85c114b38>
b=singleton.getinstance()#<__main__.singleton object at 0x000001c85c114b38>
print(a)
print(b)
我覺得這種方式最好理解,感覺像是手動完成單例建立邏輯,但注意獲得例項一定要呼叫singleton.getinstance()方法,直接a=singleton()相當於沒用單例。
classmetasingleton(type):
__instance={}def__call__(self, *args, **kwargs):ifselfnotinmetasingleton.__instance:
metasingleton.__instance[self] = super(metasingleton,self).__call__()returnmetasingleton.__instance[self]classsingleton(metaclass=metasingleton):def__init__(self):passa=singleton()#<__main__.singleton object at 0x0000025103984cc0>
b=singleton()#<__main__.singleton object at 0x0000025103984cc0>
print(a)
print(b)
執行singleton()之後,首先會呼叫metasingleton中的call函式,如果singleton類沒有在instance中,則為其建立乙個例項,也就是正常呼叫type中的call函式,將返回的物件存在instance中,以該類名為鍵,物件為值,最後返回這個物件,若instance中有該類,那就直接返回儲存的物件。
這種方式我覺得較好,不用為每個類單獨建立單例模式,只需將元類重寫即可
這種模式的理念為:例項化的物件是不同的,但是物件的狀態,屬性是相同的,也就是單態模式。
classmonostate():
_shared_state={}def__init__(self):
self.x=1
self.__dict__=self._shared_state
a=monostate()
b=monostate()
b.x=5
print(a)#<__main__.monostate object at 0x000001c267714b38>
print(b)#<__main__.monostate object at 0x000001c267714b00>
print(a.x)#5
a.c=4
print(b.c)#4
這裡的實現方式為利用類中的dict方法,我感覺是將_shared_state賦給dict後,每個物件的dict的位址都是相同的,所以物件的屬性儲存的位置都相同,那麼乙個物件的屬性變化,其餘的屬性也會發生變化。
參考《python設計模式(第2版)》
Python設計模式之單例模式
站 物件 印表機 物件 使用類名 建立物件時,python 的直譯器首先 會 呼叫 new 方法為物件 分配空間。new 是乙個 由object基類提供的內建的靜態方法,主要作用有兩個 python 的直譯器獲得物件的 引用 後,將引用作為 第乙個引數,傳遞給 init 方法。重寫 new 方法 的...
Python設計模式之單例模式
單例模式屬於建立型模式,它提供了一種建立物件的最佳方式。這種模式涉及到乙個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。這個類提供了一種訪問其唯一的物件的方式,可以直接訪問,不需要例項化該類的物件。單例模式是獲取全域性狀態的一種相當好的方法,但這也是對於單例模式的主要批評之處,因為在...
Python之單例設計模式
單例是一種設計模式,應用該模式的類只會生成乙個例項。單例模式保證了在程式的不同位置都可以且僅可以取到同乙個物件例項 如果例項不存在,會建立乙個例項 如果已存在就會返回這個例項。因為單例是乙個類,所以你也可以為其提供相應的操作方法,以便於對這個例項進行管理。以下是實現方法索引 使用 new 方法在創造...