Python 上下文管理器:使用區塊建立自訂

了解如何用 Python 編寫自訂上下文管理器。掌握 contextmanager 裝飾器和 __enter__/__exit__ 方法以確保資源安全。

在編輯器中嘗試

概述

上下文管理器是 Python 中的一種優雅機制,旨在處理外部資源的設定和拆卸。在軟體中,許多操作需要成對的操作:開啟和關閉檔案、連接和斷開與資料庫的連接,或取得和釋放鎖。如果程式在設定步驟之後但在拆卸步驟之前崩潰,這些資源將保持鎖定在記憶體中。上下文管理器保證在所有情況下都能安全地清理資源。

呼叫上下文管理器的標準方法是使用“with”語句。在底層,「with」語句中使用的任何物件都必須實作上下文管理器協定。此協定由兩個特殊方法組成:`__enter__()`和`__exit__()`。當「with」區塊開始時,呼叫「__enter__()」來準備資源。當“with”區塊完成或引發異常時,會自動觸發“__exit__()”,接收有關任何引發的異常的信息,以便它可以處理清理或抑制錯誤。

對於簡單的用例,使用「__enter__」和「__exit__」方法編寫類別可能會感覺很冗長。為了簡化這一點,Python 的標準庫提供了“contextlib”模組,該模組具有“@contextmanager”裝飾器。這個裝飾器可讓您編寫一個包含單一「yield」語句的簡單產生器函數。 「yield」之前的程式碼充當設置,產生的值充當資源,「yield」之後的程式碼代表清理。掌握上下文管理器可確保您的應用程式保持無洩漏。

程式碼和執行輸出

實作 __enter__ 和 __exit__ 的自訂類別來管理執行日誌記錄邊界。

context_managers.py
在編輯器中嘗試
class CustomManager:
    def __enter__(self):
        print("--> Resource Setup: Entering the block")
        return "RESOURCE_KEY"

    def __exit__(self, exc_type, exc_value, traceback):
        print("<-- Resource Teardown: Exiting the block")
        if exc_type:
            print(f"Exception Intercepted: {exc_value}")
        return True  # Suppress exceptions

with CustomManager() as res:
    print(f"Working inside block with resource: {res}")
    # Force an error to verify exception handling
    x = 1 / 0
print("Program continues running safely.")
端子輸出
--> Resource Setup: Entering the block
Working inside block with resource: RESOURCE_KEY
<-- Resource Teardown: Exiting the block
Exception Intercepted: division by zero
Program continues running safely.

逐步實施

  • 管理資料庫事務(成功時提交,錯誤時回滾)
  • 多線程程式碼中取得和釋放線程鎖
  • 在單元測試腳本期間重定向標準輸出 (stdout)

常見問題解答

如何抑制自訂上下文管理器中的異常?

透過從 __exit__ 方法傳回 True。如果它傳回 True,則區塊內引發的任何異常都將被抑制。

您可以在一個語句中組合多個上下文管理器嗎?

是的,您可以用逗號分隔它們,例如, open('file1.txt') as f1, open('file2.txt') as f2:。

相關主題

推薦的 Python 資源

透過相關的互動式教學、備忘單和程式碼比較來擴展您的知識。