基本概念
·上下文管理协议(Context Management Protocol)
包含方法__enter__ 和 __exit__,支持该协议的对象要实现这两个方法。
·上下文管理器( Content Manager )
支持上下文管理协议的对象,实现了__enter__ / __exit__方法。上下文管理器定义执行with语句时要建立的运行时上下文,负责执行with语句块上下文的进入和退出操作。通常使用with语句调用上下文管理器。
·运行时上下文( runtime context )
由上下文管理器创建,通过上下文管理器的__enter和__exit__方法实现,__enter方法在语句体执行之前进入运行时上下文,__exit__在语句题执行完成后从上下文运行时退出。
·上下文表达式(Context Expression)
with 语句中跟在关键字with之后的表达式,该表达式返回一个上下文管理器对象。
·语句体(with-body)
with语句包裹起来的代码块,在执行语句体之前调用上下文管理器的__enter__方法,执行完语句体之后会执行__exit__方法。
with不是上下文管理器。with只是一个语句。实现了__enter__和__exit__这两个上下文管理协议方法的对象,都被称作上下文管理器。 上下文管理器被with调用时,会创建运行时上下文,__enter__在语句体执行之前进入运行时上下文,__exit__负责在语句执行完成 之后退出。
with
with语句用上下文管理器定义的方法包裹一段代码的执行,等价于try…except..finally。with的主要作用是相当于finally。
一、多个上下文管理器
withA()asa,B()asb: suite
二、上下文管理器类型
context manager 是Python中with语句用来定义运行时上下文的对象,上下文管理器控制着进/出运行时上下文的功能,上下文管理器通常由with语句出发,也可以直接通过他们的方法来调用它们。上下文管理器通常用于保存和恢复各式各样的全局状态、加解锁资源和关闭文件的文件等。
自定义上下文管理器
classTraceBlock: defmessage(self,arg): print('running'+arg) def__enter__(self): print('startingwithblock') returnself def__exit__(self,exc_type,exc_val,exc_tb): ifexc_typeisNone: print('exitednormally') else: print('raiseanexception'+str(exc_type)) returnFalse if__name__=='__main__': withTraceBlock()asaction: action.message('test1') raiseException print('reached')
上下文装饰器
因为自定义装饰器比较麻烦,用contextlib.contextmanager将生成器转化为上下文管理器,不必创建一个类或单独指定__enter__和__exit__方法。
@contextmanager defmessage(arg): print('running'+arg) yield print('hello') if__name__=='__main__': withmessage('hell'): print('ok')
装饰器,用来装饰一个生成器函数,使这个生成器函数称为一个上下文管理器。
包含yield的函数才是生成器函数,即contextmanager装饰的函数必须含有yield!
@contextmanager defmake_context(): print('enter') try: yield{} exceptExceptionaserr: print('error',err) finally: print('exit') if__name__=='__main__': withmake_context()asvalue: raiseException print(value)
生成器函数中yield之前的语句在__enter__方法中执行;yield之后的语句在__exit__中执行;yield产生的值赋值给as子句中的variable变量。如果有异常产生,在上面的例子中,能够被except捕获。
原文来自:https://www.py.cn
暂无评论内容