Python概念-上下文管理协议中的__enter__和__exit__
上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围。一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存)。它的语法形式是with…as…
所谓上下文管理协议,就是咱们打开文件时常用的一种方法:with
__enter__(self):当with开始运行的时候触发此方法的运行
__exit__(self, exc_type, exc_val, exc_tb):当with运行结束之后触发此方法的运行
exc_type如果抛出异常,这里获取异常的类型
exc_val如果抛出异常,这里显示异常内容
exc_tb如果抛出异常,这里显示所在位置
代码示例:
1 class Sample: 2 def __enter__(self): 3 print "In __enter__()" 4 return "Foo" 5 6 def __exit__(self, type, value, trace): 7 print "In __exit__()" 8 9 def get_sample(): 10 return Sample() 11 12 with get_sample() as sample: 13 print "sample:", sample
输出如下:
1 In __enter__() 2 sample: Foo 3 In __exit__()
__enter__()
方法被执行 __enter__()
方法返回的值 – 这个例子中是”Foo”,赋值给变量’sample’
执行代码块,打印变量”sample”的值为 “Foo” __exit__()
方法被调用
改一下代码,看看具体如何工作的:
1 class Sample: 2 def __enter__(self): 3 return self 4 def __exit__(self, type, value, trace): 5 print "type:", type 6 print "value:", value 7 print "trace:", trace 8 9 def do_something(self): 10 bar = 1/0 11 return bar + 10 12 13 with Sample() as sample: 14 sample.do_something()
代码执行后:
1 type: <type 'exceptions.ZeroDivisionError'> 2 value: integer division or modulo by zero 3 trace: <traceback object at 0x1004a8128> 4 Traceback (most recent call last): 5 File "./with_example02.py", line 19, in <module> 6 sample.do_somet hing() 7 File "./with_example02.py", line 15, in do_something 8 bar = 1/0 9 ZeroDivisionError: integer division or modulo by zero
开发库时,清理资源,关闭文件等等操作,都可以放在__exit__
方法当中。因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。