Python 上下文管理器(Context Manager)教學 | Python
在 Python 中,上下文管理器(Context Manager) 是一種優雅的資源管理機制。透過 with 語句,我們可以確保資源在使用完畢後被正確釋放,無論過程中是否發生錯誤。
什麼是上下文管理器?
上下文管理器(Context Manager)用來管理資源的生命週期。最常見的應用就是檔案操作:
# 使用 with 語句開啟檔案(推薦)
with open("example.txt", "w") as f:
f.write("Hello, Python!")
# 離開 with 區塊後,檔案會自動關閉
如果不使用 with,你需要手動管理資源釋放,程式碼既冗長又容易出錯:
f = open("example.txt", "w")
try:
f.write("Hello, Python!")
finally:
f.close() # 必須確保關閉
__enter__ 和 __exit__ 方法
上下文管理器的核心是兩個魔術方法(Magic Methods):__enter__ 和 __exit__:
class MyContext:
def __enter__(self):
print("進入上下文")
return self # 回傳值會綁定到 as 後面的變數
def __exit__(self, exc_type, exc_val, exc_tb):
print("離開上下文")
return False # False 表示不抑制例外
with MyContext() as ctx:
print("執行操作")
# 輸出:
# 進入上下文
# 執行操作
# 離開上下文
自訂計時器範例
來看一個實用的範例——測量程式碼的執行時間:
import time
class Timer:
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print(f"耗時:{time.time() - self.start:.4f} 秒")
return False
with Timer():
total = sum(range(1_000_000))
# 輸出:耗時:0.0312 秒(實際時間依環境而異)
使用 contextlib 簡化實作
contextlib 模組的 @contextmanager 裝飾器(Decorator)讓你用生成器函式就能建立上下文管理器:
from contextlib import contextmanager
import time
@contextmanager
def timer():
start = time.time()
yield # yield 之前是 __enter__,之後是 __exit__
print(f"耗時:{time.time() - start:.4f} 秒")
with timer():
total = sum(range(1_000_000))
實用範例:資料庫連線管理
import sqlite3
from contextlib import contextmanager
@contextmanager
def db_connection(db_path):
conn = sqlite3.connect(db_path)
try:
yield conn
conn.commit() # 正常結束時提交
except Exception:
conn.rollback() # 發生錯誤時回滾
raise
finally:
conn.close() # 無論如何都關閉連線
with db_connection("mydb.sqlite") as conn:
cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS users (name TEXT)")
總結
上下文管理器是 Python 中管理資源的最佳實踐。透過 __enter__ 和 __exit__ 方法或 contextlib.contextmanager 裝飾器,你可以確保檔案、資料庫連線等資源被正確釋放。希望這篇文章能幫助你更好地理解並運用上下文管理器。
如果你想了解例外處理的基礎知識,請參考 Python 錯誤處理教學。
關於 __enter__ 和 __exit__ 等魔術方法的完整介紹,請閱讀 Python 魔術方法(Magic Methods)教學。