Python 單例模式

首先,咱們先建立一個測試用例python

def test_sig(sig_class):
    a = sig_class(1)
    print("a = {}(1)\na.value={}".format(sig_class.__name__, a.value))
    b = sig_class(2)
    print("b = {}(2)\nb.value={}".format(sig_class.__name__, b.value))
    print("Now a.value={}".format(a.value))
    print("a is b: {}".format(a is b))

__new__ 方法

class Singletone():
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            # 注意,這裏的__new__不接受參數
            # 參考: https://stackoverflow.com/questions/34777773
            cls._instance = super().__new__(cls)
            return cls._instance
        return cls._instance
    
    def __init__(self, n):
        self.value = n

test_sig(Singletone)

輸出以下:測試

a = Singletone(1)
a.value=1
b = Singletone(2)
b.value=2
Now a.value=2
a is b: True

在py3.3後,若是同時建立__init____new____new__裏,就不要再傳參數了。不然就會TypeError: object() takes no parameterscode

元類

class Single(type):
    # 這裏建立了一個Single元類,
    # 注意這裏使用一個字典,而不是直接用一個None值,
    # 這樣,任何使用該元類的子類,都將是單例模式,並且互不污染
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if not cls._instances:
            # 注意,這裏使用的是__call__語句,與__new__不一樣,傳入的參數也不一樣。
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]
            

class Singletone2(metaclass=Single):
    def __init__(self, n):
        self.value = n

test_sig(Singletone2)

輸出以下:orm

a = Singletone2(1)
a.value=1
b = Singletone2(2)
b.value=1
Now a.value=1
a is b: True

你也能夠使用裝飾器,我的感受和元類差很少,可是元類更優雅。這裏就不展現裝飾器的用法了。it

相關文章
相關標籤/搜索