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())