1、概念python
上下文管理器:就是實現了上下文管理協議的對象。主要用於保存和恢復各類全局狀態,關閉文件等。上下文管理器自己是一種裝飾器。函數
上下文容許能夠自動的開始和結束一些和事情。例如當利用with...as打開一個文件時,python就自動建立了一個上下文管理器。spa
2、上下文管理協議code
上下文管理協議包含兩個方法:對象
contextmanager.__enter__():with語句中的代碼塊執行前,會執行__enter__(),返回的值將賦值給with句中的as後的變量。blog
contextmanager.__exit__():with語句中的代碼塊執行結束或者出錯,會執行__exit__()。it
3、實例 with...as 代替try...except...finally打開文件class
# 錯誤的寫法
try: f = open("xxx") do something except: do something finally: f.close ##################
# 正確的寫法
'''要寫finally,是由於防止程序拋出異常最後不能關閉文件, 可是須要關閉文件有一個前提就是文件已經打開了。 在第一段錯誤代碼中, 若是異常發生在f=open(‘xxx’)的時候,好比文件不存在, 立馬就能夠知道執行f.close()是沒有意義的,改正後的解決方案就是第二段代碼'''
try: f = open("xxx")
except: print("fail to open") exit(-1) try: do something except: do something finally: f.close()
with...as...:變量
#打開一個文件並保證最後關閉它
with open("xxx") as f: data = f.read() do something with data # 打開多個
with open("xxx") as f1, open("yyy") as f2: do something with f1, f2
4、自定義上下文管理器object
class MyContextManager(object): def __init__(self): print("init 函數被調用") def __enter__(self): print("enter函數被調用,返回一個對象") return self def __exit__(self, exc_type, exc_val, exc_tb): print("exit 函數被調用") with MyContextManager(): print("建立實例作點什麼") ################ #結果:
init 函數被調用 enter函數被調用,返回一個對象 建立實例作點什麼 exit 函數被調用