Python 中的單例設計模式

Manav Narula 2023年1月30日
  1. 在 Python 中使用裝飾器實現單例設計模式
  2. 在 Python 中使用基類實現單例設計模式
  3. 在 Python 中使用元類實現單例設計模式
  4. 在 Python 中使用模組實現單例設計模式
Python 中的單例設計模式

設計模式可以代表一些程式碼來解決問題。單例就是這樣一種設計模式,我們可以在 Python 中建立一個類的不同物件。

此模式僅限制給定類的一個物件。有幾種方法可以在 Python 中模擬這種模式。

在 Python 中使用裝飾器實現單例設計模式

Python 中的裝飾器是可以將其他函式和物件作為引數並修改其行為的函式。要使用裝飾器,我們使用 @ 符號。

我們可以使用它們來實現單例設計模式。

看下面的例子,

def singleton_dec(class_):
    instances = {}

    def getinstance(*args, **kwargs):
        if class_ not in instances:
            instances[class_] = class_(*args, **kwargs)
        return instances[class_]

    return getinstance


@singleton_dec
class Sample:
    def __init__(self):
        print("Object created.")


x = Sample()
y = Sample()
print(x, y)

輸出:

Object created.
<__main__.Sample object at 0x0000015E72D3CA48> <__main__.Sample object at 0x0000015E72D3CA48>

在上面的例子中,我們建立了一個裝飾器,它將整個類作為引數。這個裝飾器允許我們實現單例物件,這可以通過 xy 的位置來確認。

為 Singleton 使用裝飾器的缺點是最終的類 Sample 變成了一個函式,所以我們不能使用類方法。

在 Python 中使用基類實現單例設計模式

基類是一個特殊的類,我們可以從中派生出其他類。沒有建立此基類的例項。

我們可以使用基類為 Python 中的 Singleton 提供結構。

例如,

class Singleton_base(object):
    _instance = None

    def __new__(class_, *args, **kwargs):
        if not isinstance(class_._instance, class_):
            class_._instance = object.__new__(class_, *args, **kwargs)
        return class_._instance


class Sample1(Singleton_base):
    def __init__(self):
        print("Object created.")


x = Sample1()
y = Sample1()
print(x, y)

輸出:

Object created.
Object created.
<__main__.Sample object at 0x0000015E72D3F388> <__main__.Sample object at 0x0000015E72D3F388>

這是一種有效的方法;但是,當由於多重繼承而涉及多個類時,可能會出現錯誤。

在 Python 中使用元類實現單例設計模式

元類是 Python 中一個非常有趣的特性,因為它可以定義類物件的行為。我們可以說它是一個類為一個類。

在 Python 2 中,我們在類中新增了 __metaclass__ 屬性。在 Python 3 中,我們可以將其作為引數新增到類中。

我們可以利用這個特性在 Python 中實現 Singleton 設計。

例如,

class Singleton_meta(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton_meta, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class Sample(metaclass=Singleton_meta):
    def __init__(self):
        print("Object created.")


x = Sample()
y = Sample()
print(x, y)

輸出:

Object created.
<__main__.Sample object at 0x0000015E72D3FF88> <__main__.Sample object at 0x0000015E72D3FF88>

這是元類的恰當應用,實現了自動繼承。

在 Python 中使用模組實現單例設計模式

在 Python 中單例的最簡單和最基本的實現可能是使用模組。

我們知道我們可以在 Python 中建立模組。一個只包含函式的模組可以作為單例,這是因為它將所有這些函式繫結到模組。

作者: Manav Narula
Manav Narula avatar Manav Narula avatar

Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.

LinkedIn