如何實現上下文管理器
阿新 • • 發佈:2021-08-10
上下文管理器with
首先我們需要了解什麼上下文管理器是做什麼?
以下通過一個例子讓大家明白。
# 例1 常規寫法
fp = open('a.txt')
fp.read()
fp.close()
# 例2 自帶上下文管理器寫法with
with open('a.txt') as fp:
fp.read()
我們通過以上例子可以看出,
- 使程式碼寫的更加簡單了
- 實現了檔案的自動關閉,避免了檔案的開啟忘記關閉的現場產生
如何實現自定義一個上下文管理器的方法呢?
1.自定義上下文管理器類
-
1.需要實現__enter__魔法方法
此方法主要是在操作之前的前置操作
-
2.需要實現__exit__魔法方法
此方法用於操作完成之後的最後收尾
例題:自定義檔案類
class MyFile(): def __init__(self, path, mode, code='utf-8'): self.path = path self.mode = mode self.code = code def __enter__(self): self.f = open(self.path, mode=self.mode, encoding=self.code) print('成功建立檔案') return self.f def __exit__(self, exc_type, exc_val, exc_tb): self.f.close() print('成功關閉檔案') if __name__ == '__main__': with MyFile('a.txt', 'wt') as f: f.write('abc') print(f) # 輸出結果: # 成功建立檔案 # <_io.TextIOWrapper name='a.txt' mode='wt' encoding='utf-8'> # 成功關閉檔案
通過以上例子可以看出:
- 上下文管理器,在建立檔案之前,是通過__enter__魔法方法來實現的
- 然後在檔案操作執行完成之後,通過__exit__魔法方法自動實現關閉的功能
2.自定義生成器函式+上下文管理器的裝飾方法 生成上下文管理器
-
首先需要 from contextlib import contextmanager
匯入contextmanager裝飾器
-
其次製作一個生成器,然後用該裝飾器去裝飾即可.
這樣就可以達到製作一個上下文管理器的目的了
from contextlib import contextmanager @contextmanager def fun(path, mode, code='utf-8'): f = open(path, mode=mode, encoding=code) try: print('生成檔案了') yield f finally: f.close() print('關閉檔案了') if __name__ == '__main__': with fun('b.tat', 'wt') as f: f.write('b') print(f) # 輸出結果: # 生成檔案了 # <_io.TextIOWrapper name='b.tat' mode='wt' encoding='utf-8'> # 關閉檔案了
通過以上方法可以看出,通過自定義生成器也能製作一個上下文管理器
在try和yield之間 可以寫函式體的功能,finally 實現最後完成之後要做的操作部分!
這樣我們就完成了如何從類和函式來製作上下文管理器!
新人若有寫的不足或者疏漏錯誤的地方,歡迎大家指出,感謝你的觀看!