上下文管理器(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语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。