一、什麼是上下文管理器
我們在處理檔案的時候經常看到下面這樣的程式碼,它即是上下文管理器:
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())
輸出結果
需要注意的是:
__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())