專家推薦一文搞懂Python上下文管理器

一、什麼是上下文管理器

我們在處理檔案的時候經常看到下面這樣的程式碼,它即是上下文管理器:

with open(‘test。txt’, encoding=‘utf-8’) as f: print(f。readlines())

它的含義是開啟當前目錄下的text。txt檔案並列印它裡面的內容,與下面的程式碼效果是一樣的:

f = open(‘test。txt’, encoding=‘utf-8’)print(f。readlines())f。close()

對比兩種寫法能夠發現,使用

with

自動執行了

f。close()

(關閉檔案)的這步操作,能夠少寫一點程式碼。

那這樣的上下文管理器是怎麼實現的,下面為你講解。

文章目錄

一、什麼是上下文管理器

二、如何實現上下文管理器

2。 透過contextlib實現

二、如何實現上下文管理器

1。 透過類實現

如果要實現上面

open

上下文管理器功能,我們可以透過建立一個類,並新增

__enter__

__exit__

方法即可,如下面的程式碼所示:

class DiyOpen(object): def __init__(self, filename, **kwargs): self。f = open(filename, **kwargs) def __enter__(self): return self。f def __exit__(self, exc_type, exc_val, exc_tb): print(‘關閉檔案’) self。f。close()with DiyOpen(‘test。txt’, encoding=‘utf-8’) as f: print(f。readlines())

輸出結果

[‘第一行\n’, ‘第二行\n’, ‘第三行’]關閉檔案

可以看到在我們打印出檔案的內容後,自動執行了關閉檔案的操作。

__enter__

__exit__

的含義是什麼,

__exit__

後面的

exc_type, exc_val, exc_tb

又是什麼意思呢?

1)_

enter

_

__enter__

相對來說好理解得多,當出現with語句時,它就會被觸發,有返回值時,會把返回值賦值給

as

宣告的變數,也就是我們上面的

as f

中的

f

2)_

exit

_

__exit__

是在with執行完成後自動執行的,他後面的引數含義如下:

exc_type:異常型別

exc_val:異常原因

exc_tb:堆疊追蹤資訊

當with中執行的程式碼報錯時,除了不繼續執行with包含的程式碼外,還會將報錯資訊放入上面的三個引數中,例如下面的程式碼:

class DiyOpen(object): def __init__(self, filename, **kwargs): self。f = open(filename, **kwargs) def __enter__(self): return self。f def __exit__(self, exc_type, exc_val, exc_tb): print(exc_type) print(exc_val) print(exc_tb) self。f。close()with DiyOpen(‘test。txt’, encoding=‘utf-8’) as f: print(f。no())

輸出結果

‘_io。TextIOWrapper’ object has no attribute ‘no’

需要注意的是:

__exit__

2。 透過contextlib實現

Python內建了

contextlib

這個模組用於實現上下文管理功能,它是透過生成器

yield

實現的,這個模組讓我們不必再建立類和__enter__和__exit__了。

透過

contextlib

實現open功能的程式碼如下:

from contextlib import contextmanager@contextmanagerdef diy_open(filename, **kwargs): f = open(filename, **kwargs) # __init__ try: yield f # __enter__ finally: # __exit__ f。close()with diy_open(‘test。txt’, encoding=‘utf-8’) as f: print(f。readlines())