1. 程式人生 > >python單例模式三種實現方法

python單例模式三種實現方法

1.方法1,程式執行過程中,某個類物件只有1個,該類物件的例項物件可以有無數個,根絕這點,讓類物件持有一個例項化物件,重寫類物件的__new__方法,始終返回持有的這個例項化物件,即可實現單例模式。
class Person1:
    _single = None
    def __new__(cls, *args, **kwargs):
        if not cls._single:
            cls._single = object.__new__(cls,*args,**kwargs)
        return cls._single

p1 = Person1()
p2 = Person1()
print(id(p1)==id(p2)) 

輸出:True。

注意__new__方法中的cls是類物件本身,檢視cls.__class__可以輸出type。

2.方法2:裝飾器實現。需要了解函式作用域,封閉作用域,以及函式閉包:函式閉包的特性,用人話來講就是,巢狀定義在非全域性作用域裡面的函式能夠記住它在被定義的時候它所處的封閉名稱空間。

def dec(cls):
    dct = dict()
    def func(*args,**kwargs):
        k = '{}{}{}'.format(cls.__name__,args,kwargs)
        print('args',args)
        print('kwargs',kwargs)
        print('cls:',cls.__class__) # cls: <class 'type'> 是類物件
        if k not in dct:
            # v = object.__new__(cls,*args,**kwargs)
            v = cls(*args,**kwargs) # cls是類物件
            dct[k] = v
        return dct[k]
    return func

@dec
class Person2():
    pass

p1 = Person2()
p2 = Person2()
print(p1.__class__) # <class '__main__.Person2'>
print(id(p1)==id(p2)) # True

3.方法3:元類實現,需要了解元類的原理,如何修改類。

class Singleton(type):
    _single = None
    def __call__(self, *args, **kwargs):
        if not self._single:
            self._single = super(Singleton,self).__call__(*args,**kwargs)
        return self._single

class P(metaclass=Singleton):
    pass

p1 = P()
p2 = P()
print(id(p1)==id(p2))