什麼是Python中Context上下文管理器

banq發表於2024-06-15

上下文管理器是 Python 的一個實用功能。它們之所以如此有用,是因為它們能夠正確響應模式。在很多情況下,我們想要執行一些具有前置條件和後置條件的程式碼,這意味著我們想要分別在主要操作之前和之後執行某些操作。上下文管理器是這些情況下非常有用的工具。

資源處理上下文
大多數情況下,我們看到上下文管理器與資源管理有關。例如,在開啟檔案的情況下,我們希望確保在處理後關閉它們,或者如果我們開啟與服務甚至套接字的連線,我們希望確保相應地關閉它。在所有這些情況下,我們都需要考慮釋放已分配的所有資源,而一個乾淨的方法是使用 finally 塊。

讓我們看一個例子:

file_data = open(filename)
try:
    process_file(file_data)
finally:
    file_data.close()


如下所示,使用 with 語句是實現上述任務的更好的 pythonic 方法:

with open(filename) as file_data:
    process_file(file_data)

with 語句(PEP-343)進入上下文管理器

在這種情況下,open 函式實現了上下文管理器協議,這意味著當程式碼塊結束時,檔案將被自動關閉,即使發生了異常。Python 中的 with 語句是一個強大的工具,旨在簡化常見的資源管理模式。

上下文管理器由兩個神奇的方法組成:

  • __enter__ 
  • __exit__

在上下文管理器的第一行,with 語句將呼叫第一個方法 __enter__ ,這個方法返回的內容將被賦值給 "as "後面的變數。

執行這一行後,程式碼將進入一個新的上下文,在這個上下文中可以執行任何其他 Python 程式碼。

在該程式碼塊的最後一條語句之後,上下文將被退出,這意味著 Python 將呼叫 __exit__ 方法。

如果上下文管理器程式碼塊中出現異常或錯誤,__exit__ 方法仍會被呼叫,這有助於安全地管理清理工作。

上下文管理器是一種很好的方法,可以將應該保持獨立的程式碼部分隔離開來。


自定義上下文管理器
除了資源處理上下文管理器,我們還可以建立自定義上下文管理器。讓我們來看一個自定義上下文管理器的例子,它可以測量程式碼塊的執行時間:

import time

class Timer:
    def __init__(self):
        self.start = None
        self.end = None
        self.elapsed = None

    def __enter__(self):
        self.start = time.time()  
        return self # This allows you to get data within the with block
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end = time.time()
        self.elapsed = self.end - self.start

with Timer() as timer:
    # Code to be timed goes here
    time.sleep(1)  # Simulate some work

print(f<font>"Elapsed time: {timer.elapsed:.4f} seconds")

如上例所示,with 語句建立了一個 Timer 上下文管理器例項,而要計時的程式碼就在 with 程式碼塊中。退出程式碼塊後,經過的時間會自動計算出來,並顯示在 timer.elapsed 屬性中。簡而言之,該計時器可用於對程式碼的各個部分進行剖析。

相關文章