首頁  >  文章  >  後端開發  >  Python 中的單例模式

Python 中的單例模式

黄舟
黄舟原創
2017-02-04 16:38:191353瀏覽

單例模式

單例模式(Singleton Pattern)是一種常用的軟體設計模式,此模式的主要目的是確保某一個類別只有一個實例存在。當你希望在整個系統中,某個類別只能出現一個實例時,單例物件就能派上用場。

例如,某個伺服器程式的設定資訊存放在一個檔案中,客戶端透過一個 AppConfig 的類別來讀取設定檔的資訊。如果在程式運行期間,有很多地方都需要使用設定檔的內容,也就是說,很多地方都需要建立 AppConfig 物件的實例,這就導致系統中存在多個 AppConfig 的實例對象,而這樣會嚴重浪費記憶體資源,尤其是在設定檔內容很多的情況下。事實上,類似 AppConfig 這樣的類,我們希望在程式運行期間只存在一個實例物件。

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

  • 使用模組

  • 使用__new__

  • 類使用裝飾器使用裝飾器(類)

  • 使用模組

其實,Python 的模組就是天然的單例模式,因為模組在第一次導入時,會產生.pyc 文件,當第二次導入時,就會直接載入 .pyc 文件,而不會再次執行模組程式碼。因此,我們只要把相關的函數和資料定義在一個模組中,就可以獲得一個單例物件了。如果我們真的想要一個單例類,可以考慮這樣做:

# 
mysingleton.py
class My_Singleton(object):
    def foo(self):
        pass
 
my_singleton = My_Singleton()
將上面的程式碼保存在檔案mysingleton.py 中,然後這樣使用:

from 
mysingleton import my_singleton
 
my_singleton.foo()

使用__new__

為了使類別只能出現一個實例,我們可以使用__new__ 來控制實例的建立過程,程式碼如下:

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kw):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)  
        return cls._instance  
 
class MyClass(Singleton):  
    a = 1
在上面的程式碼中,我們將類別的實例和一個類別變數_instance 關聯起來,如果cls._instance 為None 則建立實例,否則直接傳回 cls._instance。

執行情況如下:

>>> one = MyClass()
>>> two = MyClass()
>>> one == two
True
>>> one is two
True
>>> id(one), id(two)
(4303862608, 4303862608)

使用裝飾器

我們知道,裝飾器(decorator)可以動態地修改一個類別或函數的功能。這裡,我們也可以使用裝飾器來裝飾某個類,使其只能產生一個實例,程式碼如下:

from 
functools import wraps
 
def singleton(cls):
    instances = {}
    @wraps(cls)
    def getinstance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return getinstance
 
@singleton
class MyClass(object):
    a = 1
在上面,我們定義了一個裝飾器singleton,它傳回了一個內部函數getinstance,該函數會判斷某個類別是否在字典instances 中,如果不存在,則會將 cls 作為 key,cls(*args, **kw) 作為 value 存到 instances 中,否則,直接傳回 instances[cls]。

使用metaclass

元類別(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]
     
    # 
    Python2
    class MyClass(object):
        __metaclass__ = Singleton
     
    # 
    Python3
    # 
    class MyClass(metaclass=Singleton):
    #    pass

  • 小結

Python 的模組是天然的單例,這用夠例當然,我們也可以使用裝飾器、元類等方法


以上就是Python 中的單例模式 的內容,更多相關內容請關注PHP中文網(www.php.cn)!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn