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

posted @ 2018-10-24 17:17  花歌  阅读(375)  评论(0编辑  收藏  举报