Python中的單例模式

來源:互聯網
上載者:User

標籤:ini   elf   無法   imp   代碼   col   訪問   port   塊代碼   

在python中,我們可以用多種方法來實現單例模式:

  - 使用模組

  - 使用__new__

  - 使用裝飾器

  - 使用元類(metaclass)

使用模組

  其實,python的模組就是天然的單例模式,因為模組在第一次匯入時,會產生.pyc檔案,當第二次匯入時,就會直接載入.pyc檔案,而不會再次執行模組代碼。因此我們只需把相關的函數和資料定義在一個模組中,就可以獲得一個單例對象了。

# mysingle.pyclass MySingle:
  def foo(self):
    pass

sinleton = MySingle()
將上面的代碼儲存在檔案mysingle.py中,然後這樣使用:
from mysingle import sinleton
singleton.foo()

使用__new__

為了使類只能出現一個執行個體,我們可以使用__new__來控制執行個體的建立過程,代碼如下:

class Singleton(object):    def __new__(cls):        # 關鍵在於這,每一次執行個體化的時候,我們都只會返回這同一個instance對象        if not hasattr(cls, ‘instance‘):            cls.instance = super(Singleton, cls).__new__(cls)        return cls.instance obj1 = Singleton()obj2 = Singleton() obj1.attr1 = ‘value1‘print obj1.attr1, obj2.attr1print obj1 is obj2 輸出結果:value1  value1

使用裝飾器:

我們知道,裝飾器可以動態修改一個類或函數的功能。這裡,我們也可以使用裝飾器來裝飾某個類,使其只能產生一個執行個體:

def singleton(cls):    instances = {}    def getinstance(*args,**kwargs):        if cls not in instances:            instances[cls] = cls(*args,**kwargs)        return instances[cls]    return getinstance@singletonclass MyClass:    a = 1c1 = MyClass()c2 = MyClass()print(c1 == c2) # True


在上面,我們定義了一個裝飾器 singleton,它返回了一個內建函式 getinstance
該函數會判斷某個類是否在字典 instances 中,如果不存在,則會將 cls 作為 key,cls(*args, **kw) 作為 value 存到 instances 中,
否則,直接返回 instances[cls]

使用metaclass(元類)

元類可以控制類的建立過程,它主要做三件事:

  - 攔截類的建立

  - 修改類的定義

  - 返回修改後的類

使用元類實現單例模式:

class Singleton2(type):    def __init__(self, *args, **kwargs):        self.__instance = None        super(Singleton2,self).__init__(*args, **kwargs)    def __call__(self, *args, **kwargs):        if self.__instance is None:            self.__instance = super(Singleton2,self).__call__(*args, **kwargs)        return self.__instanceclass Foo(object):    __metaclass__ = Singleton2 #在代碼執行到這裡的時候,元類中的__new__方法和__init__方法其實已經被執行了,而不是在Foo執行個體化的時候執行。且僅會執行一次。foo1 = Foo()foo2 = Foo()print (Foo.__dict__)  #_Singleton__instance‘: <__main__.Foo object at 0x100c52f10> 存在一個私人屬性來儲存屬性,而不會汙染Foo類(其實還是會汙染,只是無法直接通過__instance屬性訪問)print (foo1 is foo2)  # True

 

Python中的單例模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.