python單例模式原理及實現


python單例模式的原理及實現

什么是單例模式:
單例模式即一個類有且僅有一個實例。

為什么要用:
全局變量,因為這比函數的參數傳來傳去更容易讓人理解。確實在很多場景下用全局變量很方便。不過如果代碼規模增大,並且有多個文件的時候,全局變量就會變得比較混亂。
你可能不知道在哪個文件中定義了相同類型甚至重名的全局變量,也不知道這個變量在程序的某個地方被做了怎樣的操作。
單例模式保證了在程序的不同位置都可以且僅可以取到同一個對象實例:如果實例不存在,會創建一個實例;如果已存在就會返回這個實例。因為單例是一個類,所以你也可以為其提供相應的操作方法,以便於對這個實例進行管理。

python中,一個類創建對象實例是通過調用父類object的 __new__(cls)方法來創建對象的,因此我們可以通過重寫 __new__(cls)方法去實現類只創建一個實例

class Sun(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 = Sun()
print(id(a))
b = Sun()
print(id(b))

 

注意:

 

1)__new__方法是靜態類方法,雖然沒有加靜態類方法的裝飾器;

 

2)A繼承object類,雖然通常可以省略object字樣。但這里省略就無法執行__new__方法。若A繼承其他類,同樣可以使用object的__new__方法,也可以使用父類的__new__方法;

 

3)在實例化對象的時候,__new__方法在__init__方法之前執行;

 

4)__new__必須返回一個對象,才能給__init__初始化。

 

__init__初始化會影響屬性的內容。在使用單例模式時,盡量避免初始化屬性或者初始化屬性之前先判斷是否存在該屬性。

使用函數裝飾器實現單例

使用類裝飾器實現單例

def singleton(cls):
    _instance = {}#使用不可變的類地址作為鍵,其實例作為值,每次創造實例時,
#首先查看該類是否存在實例,存在的話直接返回該實例即可,
#否則新建一個實例並存放在字典中。
def inner(): if cls not in _instance: _instance[cls] = cls() return _instance[cls] return inner @singleton class Cls(object): def __init__(self): pass cls1 = Cls() cls2 = Cls() print(id(cls1) == id(cls2))

使用 metaclass 實現單例模式

class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class Cls4(metaclass=Singleton):
    pass

cls1 = Cls4()
cls2 = Cls4()
print(id(cls1) == id(cls2))


免責聲明!

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



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