Python 上下文管理器:使用區塊建立自訂
了解如何用 Python 編寫自訂上下文管理器。掌握 contextmanager 裝飾器和 __enter__/__exit__ 方法以確保資源安全。
概述
上下文管理器是 Python 中的一種優雅機制,旨在處理外部資源的設定和拆卸。在軟體中,許多操作需要成對的操作:開啟和關閉檔案、連接和斷開與資料庫的連接,或取得和釋放鎖。如果程式在設定步驟之後但在拆卸步驟之前崩潰,這些資源將保持鎖定在記憶體中。上下文管理器保證在所有情況下都能安全地清理資源。
呼叫上下文管理器的標準方法是使用“with”語句。在底層,「with」語句中使用的任何物件都必須實作上下文管理器協定。此協定由兩個特殊方法組成:`__enter__()`和`__exit__()`。當「with」區塊開始時,呼叫「__enter__()」來準備資源。當“with”區塊完成或引發異常時,會自動觸發“__exit__()”,接收有關任何引發的異常的信息,以便它可以處理清理或抑制錯誤。
對於簡單的用例,使用「__enter__」和「__exit__」方法編寫類別可能會感覺很冗長。為了簡化這一點,Python 的標準庫提供了“contextlib”模組,該模組具有“@contextmanager”裝飾器。這個裝飾器可讓您編寫一個包含單一「yield」語句的簡單產生器函數。 「yield」之前的程式碼充當設置,產生的值充當資源,「yield」之後的程式碼代表清理。掌握上下文管理器可確保您的應用程式保持無洩漏。
程式碼和執行輸出
實作 __enter__ 和 __exit__ 的自訂類別來管理執行日誌記錄邊界。
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 資源
透過相關的互動式教學、備忘單和程式碼比較來擴展您的知識。