python上下文管理
上下文管理
位于 with 语句后的对象,with语句会对该对象进行上下文管理,即在进入with语句块前和退出语句块时会对该对象进行一些操作,这个操作分别在__enter__(self) 和 __exit__(self)中定义。
上下文管理原理
所谓的上下文管理是对一个对象而言,可以对对象使用with语句,定义一些进入操作和退出操作,这样即使在with语句块中出现了错误或者程序退出,仍然会执行我们定义的退出操作,通常我们使用结束操作执行一些释放资源的操作,保证在出错的情况下仍然会执行。
class Point: def __enter__(self): print("enter with") return self def __exit__(self): print("exit with") p = P() with p as s: # 调用p.__enter__() ,s为__enter__的返回值 pass with Point(): # 同理 pass
exit方法的参数和返回值
__exit__是with语句退出时执行的方法,如果这个语句块是因为出现错误退出的,__exit__函数是可以将其捕获的,并提供了三个参数方便对这个类型进行处理。如果没有错误,三个参数都为None
def __exit__(self, exc_type, exc_value, exc_tb): # exc_type: 错误的类型 # exc_type:错误的值,定义错误时输入的指针 # exc_tb :错误的traceback信息 return #return值为ture或者false决定了这个错误会不会压制,为True会压制错误
上下文管理工具contextlib.contextmanager
它是一个装饰器实现的上下文管理工具,装饰一个函数(这个函数必须是生成器函数),不用向类一样实现 enter 和 exit 方法,简便了操作
import contextlib @contextlib.contextmanager def foo(): print("enter -----") # 进入with时执行。 yield 100 # with的返回值 print("") # 退出with时候执行 with foo() as f: # process # 进入和退出时候foo 函数执行
上面的函数无法解决 with 语句块中出现异常的情况。需要进一步改进,在函数中使用 try 捕异常,finally 保证 退出语句的正常执行。
@contextlib.contextmanager def foo(): print("enter -----") # 进入with时执行。 try: yield 100 # with的返回值 finally: print("exit-----") # 退出with时候执行
with foo() as f:
# process