class Open: def __init__(self,filename): self.filename = filename def __enter__(self): print("__enter__") return self def __exit__(self, exc_type, exc_val, exc_tb): print("__exit__") with Open('a.txt') as f: # with Open會觸發__enter__, __enter__返回的值會賦值給f ,而後會執行with裏面的代碼塊,最後會執行__exit__ print(f) print(f.filename) print("============>") print("============>") print("============>") print("============>") print('111111111111111111111')
返回結果:python
__enter__ # with Open觸發__enter__的執行,把返回值給了f
<__main__.Open object at 0x0000000000B9DC18> # 打印了f的內存地址
a.txt # 打印了f.filename
============> # 打印了4個print
============>
============>
============>
__exit__ # with裏面執行完畢會觸發__exit__的執行
111111111111111111111 # 最後會執行print('111111111111111111111')
來咱們看下另一種狀況:spa
class Open: def __init__(self,filename): self.filename = filename def __enter__(self): print("__enter__") return self def __exit__(self, exc_type, exc_val, exc_tb): print("__exit__")print(exc_type) print(exc_val) print(exc_tb)
with Open('a.txt') as f: print(f.filename) print(dkasfklafl) print("============>") print("============>") print("00000000")
執行結果:code
Traceback (most recent call last): File "E:/seafile backup/python3/python3 project/day 28/s1 上下文管理協議.py", line 43, in <module> print(dkasfklafl) NameError: name 'dkasfklafl' is not defined __enter__ # with Open會觸發__enter__,把返回值賦值給f a.txt # 打印f.filename __exit__ # 打印print(dkasfklafl),由於沒有這個變量,報錯,直接觸發__exit__ <class 'NameError'> # 打印一個錯誤類 name 'dkasfklafl' is not defined # 提示變量名沒有定義 <traceback object at 0x0000000000B89748> # 追蹤信息 注意:報錯以後,下面的代碼都不會運行了
# 好比:print("============>") print("============>") print("00000000")都沒有運行
會報錯,如今咱們解決剛剛的報錯blog
class Open: def __init__(self,filename): self.filename = filename def __enter__(self): print("__enter__") return self def __exit__(self, exc_type, exc_val, exc_tb): print("__exit__") print(exc_type) print(exc_val) print(exc_tb)return True
with Open('a.txt') as f: print(f) print(dkasfklafl) print("============>") print("============>") print("00000000")
執行結果內存
__enter__ # with Open觸發__enter__, __enter__返回值賦值給f <__main__.Open object at 0x000000000105DD68> # 執行print(f) __exit__ # 碰到print(dkasfklafl)異常,觸發__exit__ <class 'NameError'> # print(exc_type) 打印錯誤類型 name 'dkasfklafl' is not defined # print(exc_val) ,打印提示信息,提示變量名沒有定義 <traceback object at 0x0000000001069748> # print(exc_tb) ,打印追蹤信息 ,以後就跳出with的代碼塊,執行下面的代碼 00000000 # 執行print("00000000")