首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Python 使用 Metaclass 實作 Singleton 模式

     編輯:更多程式設計知識

Metaclass 控制類別建立過程。透過覆寫 __call__ 攔截實例化,可在類別層級實現 Singleton:首次建立實例後快取,後續呼叫回傳同一物件。

實作


class Singleton(type):
    def __call__(cls, *args, **kwargs):
        if not hasattr(cls, 'instance'):
            cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
        return cls.instance

    def __new__(cls, name, bases, dct):
        print("Singleton __new__")
        return type.__new__(cls, name, bases, dct)

    def __init__(cls, name, bases, dct):
        print("Singleton __init__")
        super(Singleton, cls).__init__(name, bases, dct)

class Cache(object):
    __metaclass__ = Singleton  # Python 2
    # Python 3: class Cache(metaclass=Singleton):

    def __new__(cls, *args, **kwargs):
        print("Cache __new__")
        return object.__new__(cls, *args, **kwargs)

    def __init__(self, *args, **kwargs):
        print("Cache __init__")

    def __call__(self, *args, **kwargs):
        print("Cache __call__")

print(Cache())
print(Cache())

輸出


Singleton __new__
Singleton __init__
Singleton __call__
Cache __new__
Cache __init__
<__main__.Cache object at 0x...>
Singleton __call__
<__main__.Cache object at 0x...>  # 同一物件

關鍵點

  • Singleton.__call__ 攔截 Cache(),檢查 cls.instance。
  • __new__/__init__ 僅在首次建立時執行。
  • Python 3 語法:class Cache(metaclass=Singleton):。
  • 繼承 Singleton 的子類別各自擁有獨立 instance。

替代方案

  1. 模組層級單例:instance = Cache() 直接匯入。
  2. 裝飾器:@singleton 包裝類別。
  3. __new__ 覆寫 (不需 metaclass):

class Singleton:
    _instance = None
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

適用場景

  • 資料庫連線池、設定管理、日誌器、快取管理器等全域唯一服務。
  • Metaclass 方案適合框架層級強制所有服務類別為 Singleton。

Metaclass 是 Python 進階元編程利器,Singleton 是其經典教學範例。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved