with-as === `with` 適用於對資源進行存取的時機,使用 `with` 的話,檔案使用完之後就會自動關閉,也確保存取發生異常時,會執行後續的 error 操作。 EX:文件使用后自动关闭/线程中锁的自动获取和释放等。 雖然也可以透過以下 `try-except` 來達成一樣的目的,但比較冗長,還需要另外寫 `finally`: ```python= try: f = open("1.txt") except: print('fail to open') exit(-1) finally: data = f.read() f.close() ``` 而使用 `with` 的話,還能自動處理上下文環境產生的異常: ```python= with open("1.txt") as f: data = f.read() ``` ### 客製化 Context Manager > context manager 用來管理 context(上下文)的,誕生的初衷就在於簡化 try-finally,因此就適合應用於在需要 finally 的地方,也就是需要清理的地方,比如 > > 保證資源的安全釋放,如 file、lock、semaphore、network connection 等 > 臨時操作的復原,如果一段邏輯有 setup、prepare,那麼就會對應 cleanup、teardown。 > [ref](https://www.cnblogs.com/xybaby/p/13202496.html) 若要自行建立 context manager,需要定義類別的 `__enter__` 與 `__exit__` 兩個方法。 * `with` 在開始執行時,會執行 `__enter__` 這個函數,傳回配給的資源(例如開啟的檔案) * `with` 範圍結束時,會自動呼叫 `__exit__` 釋放資源(例如關閉檔案)。 以下是一個開檔的 context manager 範例: ```python= #/usr/bin/python # -*- coding: utf-8 -*- # 自行定義 Context Manager class File(object): def __init__(self, filename, mode): # 設定檔名與開檔模式 self.filename = filename self.mode = mode # 配給資源(開啟檔案) def __enter__(self): print("開啟檔案:" + self.filename) self.open_file = open(self.filename, self.mode) return self.open_file # 回收資源(關閉檔案) def __exit__(self, type, value, traceback): print("關閉檔案:" + self.filename) self.open_file.close() ``` 使用方式: ```python= with File("file.txt", "w") as f: print("寫入檔案...") f.write("Hello, world.") ``` 輸出 ``` 開啟檔案:file.txt 寫入檔案... 關閉檔案:file.txt ``` ## Ref. [Python 中 with用法及原理](https://blog.csdn.net/u012609509/article/details/72911564) [Python 的 with 語法使用教學:Context Manager 資源管理器](https://blog.gtwang.org/programming/python-with-context-manager-tutorial/) ###### tags: `語法相關`