python中的with上下文管理器

2021-09-09 09:26:41 字數 2388 閱讀 8473

with 語句是 pyhton 提供的一種簡化語法,確保不管使用過程中是否發生異常都會執行必要的「清理」操作,釋放資源。

在沒有學習with的句法之前,通常我們都是使用try…finally語句,即使是在出現錯誤的情況下 也能執行某些清理**。而今天學習的with語句就是對這些**功能的一些簡單封裝。

with語句通常會使用在如下的幾個環境之中:

那麼,接下來我們就舉開啟關閉檔案的例子說明:

我們先使用file()方法,看看兩者之間有什麼不同?

hosts=open('/etc/hosts')

try:

for line in hosts:

if line.startswith('#'): #startswith以『#』結尾

continue

print(line.strip())

finally:

hosts.close()

上面的**,我們是要開啟位於/etc目錄的hosts檔案,使用file()方法之後,又手動呼叫close()關閉檔案。

那麼,使用with語句之後,我們可以重寫為:

with open ('/etc/hosts') as hosts:

for line in hosts:

if line.startswith('#'): #startswith以『#』結尾

continue

print(line.strip())

with的執行過程:

在執行 with 語句時,首先執行 with 後面的 open **

執行完**後,會將**的結果通過 as 儲存到 hosts 中

然後在下面實現真正要執行的操作

在操作後面,並不需要寫檔案的關閉操作,檔案會在使用完後自動關閉

任何實現了 _enter_(self) 和 _exit_(self,exc_type,exc_value,traceback) 方法的物件都可稱之為上下文管理器,上下文管理器物件可以使用 with 關鍵字。顯然,檔案(file)物件也實現了上下文管理器協議。

從底層原理的角度來說,with語句的執行過程如下:

呼叫__enter__方法,任何返回值都會繫結到指定的as字句

執行內部**塊 呼叫__exit__方法

執行內部**塊 呼叫__exit__方法執行內部**塊 呼叫__exit__方法

我們可以模擬實現乙個自己的檔案類,讓該類實現 _enter_() 和 _exit_() 方法。

class file():

def __init__(self, filename, mode):

self.filename = filename

self.mode = mode

def __enter__(self):

print("entering")

self.f = open(self.filename, self.mode)

return self.f

def __exit__(self, *args):

print("will exit")

self.f.close()

注:當我們開啟檔案時,就會自動呼叫_enter_,最終會返回該資源物件。當退出檔案時,會自動呼叫__exit_方法,把檔案關閉,做一些清理工作。

因為 file 類實現了上下文管理器,現在就可以使用 with 語句了。

with file('out.txt', 'w') as f:

print("writing")

f.write('哈哈哈,你好啊!')

contextlib模組是實現上下文管理的另外一種方式,這個模組提供了與上下文管理器一起使用的輔助函式。它使用的是 contextmanager 裝飾器,通過 yield 將函式分割成兩部分,yield 之前的語句在\enter方法中執行,yield 之後的語句在 _exit_ 方法中執行。緊跟在 yield 後面的值是函式的返回值。

from contextlib import contextmanager

@contextmanager

def my_open(path, mode):

f = open(path, mode)

yield f

f.close()

使用:

with my_open('out.txt', 'w') as f:

f.write("hello , the ******st context manager")

參考文獻:

【python】with及上下文管理器的原理和應用

pythong高階程式設計(第二版)

上下文 上下文棧

全域性 函式 區域性 在執行全域性 前將window確定為全域性執行上下文 對全域性資料進行預處理 var定義的全域性變數 undefined,新增為window的屬性 function宣告的全域性函式 賦值 fun 新增為window的方法 this 賦值 window 開始執行全域性 在呼叫函式...

中斷上下文 程序上下文

在學習與作業系統相關的知識時候,我們經常遇到程序上下文 中斷上下文,看似熟悉又感覺不是特別清晰。這裡我們從如下幾個方面進行描述。上下文是從英文中context翻譯過來的,指的是一種環境。上下文我們看起來不怎麼熟悉,但是我們可以看context的中文翻譯,或者我們能更加的情形些。context n 語...

全域性上下文與上下文

全域性上下文由main函式載入系統的主架構和主事件迴圈和全域性資料構成。是上帝創造世界時,建立的基礎事物。萬物之始,大道至簡,衍化至繁。全域性上下文代表著程式執行所需要的基礎資源。是程式執行的基礎。全域性上下文的特徵是在程式執行期間常駐記憶體。全域性上下文的生命週期和應用程式的生命週期相同。與應用程...