with 語句用於包裝帶有使用上下文管理器定義的方法的代碼塊的執行
能夠用來替代 try
語句html
__exit__()
__enter__()
方法with
語句包含一個目標,來自 __enter__()
的返回值將被賦予它__exit__()
,若是執行語句時出現異常:將異常的類型、值、回溯信息傳給 __exit__()
;若是沒有異常:傳入 Nonetry
語句以打開文件爲例:
try
語句:python
f = open("text.txt", "r") try: print(f.read()) except Exception: print("error occurred") finally: f.close()
with
語句:express
with open("text.txt", "r") as f: print(f.read())
上下文管理器屬於上下文管理器類型 (Context Manager Types),用於 with
語句定義運行上下文
有 __enter__()
和 __exit__()
的對象均可以是上下文管理器code
contextmanager.__enter__()
以 with open() as f:
爲例:文件對象會從 __enter__()
返回自身,使得 open()
能夠被用做上下文表達式 (context expression)htm
contextmanager.__exit__(exc_type, exc_val, exc_tb)
返回 True
時表示屏蔽異常,會繼續執行 with
以後的語句;返回 False
時異常會在此方法執行結束後繼續傳播對象
實現打開文件的功能:文檔
class UserContextManager(object): def __init__(self, file_name, mode): self.file_name = file_name self.mode = mode def __enter__(self): self.f = open(self.file_name, self.mode) return self.f def __exit__(self, exc_type, exc_val, exc_tb): self.f.close() with UserContextManager("text.txt", "r") as f: print(f.read())
Python 標準庫中的 contextlib 包含許多支持 with 語句的程序
官方文檔:https://docs.python.org/zh-cn/3/library/contextlib.html#module-contextlibit
contextmanager
能夠經過一個裝飾器,實現 with
語句的功能
yield
以前的語句在 __enter__()
中執行,yield
以後的語句在 __exit__()
中執行,yield
的爲 __enter__()
的返回值io
from contextlib import contextmanager @contextmanager def user_open(path, mode): f = open(path, mode) yield f f.close() with user_open('text.txt', 'r') as f: print(f.read())