如何在Python中使用上下文管理器(with語句)
了解上下文管理器在 Python 中的工作原理。掌握with語句,管理系統資源,並編寫自訂上下文管理器。
概述
正確管理外部資源(例如關閉檔案句柄、斷開資料庫連接和釋放執行緒鎖)對於建立可靠的生產就緒軟體至關重要。未能釋放資源可能會導致記憶體洩漏、檔案鎖定錯誤和應用程式掛起。
Python 的「with」語句透過建立上下文管理器來簡化資源清理。上下文管理器保證當控制離開區塊時會自動執行清理操作,即使程式碼拋出例外狀況或提前退出。這消除了對冗長、重複的「try-finally」區塊的需求。
雖然上下文管理器最常與「open()」等內建操作相關聯,但您可以輕鬆設計自己的自訂上下文管理器。您可以透過建立一個實作「__enter__」和「__exit__」魔術方法的類別來建構它們,或者編寫一個用「contextlib.contextmanager」裝飾器裝飾的生成器函數。
程式碼和執行輸出
該腳本演示了使用類別實作和 contextlib 裝飾器在 Python 中編寫自訂上下文管理器。
context_managers.py
在編輯器中嘗試from contextlib import contextmanager
# Method 1: Class-based context manager
class CustomResource:
def __enter__(self):
print("[Resource] Opening connection...")
return self
def do_work(self):
print("[Resource] Performing action...")
def __exit__(self, exc_type, exc_val, exc_tb):
print("[Resource] Closing connection safely.")
return False
print("--- Class Context Manager ---")
with CustomResource() as resource:
resource.do_work()
# Method 2: Generator-based context manager (contextlib)
@contextmanager
def simple_timer():
print("\n[Timer] Started...")
try:
yield
finally:
print("[Timer] Finished!")
print("\n--- Decorator Context Manager ---")
with simple_timer():
print("Performing tasks inside context...")端子輸出
--- Class Context Manager ---
[Resource] Opening connection...
[Resource] Performing action...
[Resource] Closing connection safely.
--- Decorator Context Manager ---
[Timer] Started...
Performing tasks inside context...
[Timer] Finished!逐步實施
- 開啟檔案、資料庫或鎖定時使用with語句來確保資源安全。
- 使用帶有 __enter__ 和 __exit__ 魔術方法的類別定義自訂上下文管理器。
- 在生成器函數上使用 @contextlib.contextmanager 裝飾器作為更簡單的基於函數的替代方案。
- 將資源關閉作業放置在清理區塊內,以確保即使發生錯誤它們也能運作。
常見問題解答
__exit__ 方法接收哪些參數?
__exit__ 方法接收三個參數,表示異常詳細資訊(如果引發):exc_type(異常類型)、exc_val(異常值)和 exc_tb(回溯)。如果沒有發生錯誤,則所有三個都將作為 None 傳遞。
上下文管理器可以抑制異常嗎?
是的。如果 __exit__ 方法傳回真值(如 True),Python 會抑制異常並在 with 區塊之後繼續執行。如果傳回 False,則正常引發異常。
相關主題
推薦的 Python 資源
透過相關的互動式教學、備忘單和程式碼比較來擴展您的知識。