python設計模式之單例模式


一.理解單例模式

單例模式是一種創建型設計模式,它確保一個類有且只有一個特定類型的對象,並提供全局訪問點。其意圖為:

  • 確保類有且只有一個對象被創建

  • 為對象提供一個訪問點,使程序可以全局訪問該對象

  • 控制共享資源的並行訪問

簡單理解:單例即為單個實例,也就是每次實例化創建對象時獲得的都是同一個對象,當然同一個對象的屬性都是相同的,方法也是相同的,地址也是相同的,這樣給我們帶來的好處就是可以避免消耗過多的內存或CPU資源,例如數據庫類,我們希望每次都使用同一個數據庫對象來對數據庫進行操作,以維護數據的一致性。又如模塊的導入,如果沒有導入該模塊,則導入該模塊並實例化,如果已經導入,則返回該模塊的對象

二.python實現單例模式

1.基於new方法實現的單例模式


class Singleton():
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls,'instance'):
            cls.instance=super(Singleton,cls).__new__(cls)
        return cls.instance

a=Singleton()
b=Singleton()
print(a)#<__main__.Singleton object at 0x00000220866EF400>
print(b)#<__main__.Singleton object at 0x00000220866EF400>

new方法為python實例化創建對象自動執行的函數,通過重寫這個函數,使之先判斷該類中是否有instance屬性(利用反射),若沒有則為創建一個對象並為該屬性賦值,最后返回instance中的對象。通過這種方式我們實現了每次創建實例返回的都是類中的instance的值。

2.懶漢式實例化


class Singleton():
    __instance=None
    def __init__(self):
        pass
    @classmethod
    def getInstance(cls):
        if not cls.__instance:
            cls.__instance = Singleton()
        return cls.__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()相當於沒用單例。

3.基於元類的單例實現


class MetaSingleton(type):
    __instance={}
    def __call__(self, *args, **kwargs):
        if self not in MetaSingleton.__instance:
            MetaSingleton.__instance[self] = super(MetaSingleton,self).__call__()
        return MetaSingleton.__instance[self]

class Singleton(metaclass=MetaSingleton):
    def __init__(self):
        pass

a=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中有該類,那就直接返回存儲的對象。

這種方式我覺得較好,不用為每個類單獨創建單例模式,只需將元類重寫即可

三.單例模式的缺點

  • 全局變量可能在某處被修改,但開發人員仍然認為他們沒有發生變化

  • 會對同一個對象創建多個引用

  • 所有類都依賴同一個全局變量,那么他們則變的緊密耦合

四.Monostate單態模式

這種模式的理念為:實例化的對象是不同的,但是對象的狀態,屬性是相同的,也就是單態模式。


class Monostate():
    _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版)》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM