Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2798339
  • 博文数量: 471
  • 博客积分: 7081
  • 博客等级: 少将
  • 技术积分: 5369
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-04 21:55
文章分类

全部博文(471)

文章存档

2014年(90)

2013年(69)

2012年(312)

分类: Python/Ruby

2014-04-19 09:40:46

with是python2.5以后才有的,它实质是一个控制流语句,with可以用来简化try-finally语句。它的主要用法是实现一个类__enter__()和__exit__()方法,基本形式如下:

  1. class controlled_execution:
  2.     def _enter__(self):
  3.         set things up
  4.         return thing
  5.     def __exit__(self, type, value, traceback):
  6.         tear thing down
  7. with controlled_execution() as thing:
  8.     some code

 在实际的运行过程中,python会首先运行enter里的代码,返回thing,作为as 后面的变量值,然后再运行with模块中的代码,最后会自动执行exit中的代码,而不管with中的代码运行结果如何。这也就是with能简化try-finally语句的原因。所以with通常用在读取文件的操作中,将文件句柄的关闭操作放在exit方法中,这样就不会因忘记释放文件句柄而产生可能出现的错误。
另外,exit()方法的返回值可以用来指示with部分的代码出现的异常是否需要raise,如果返回false,则会raise,否则,不进行任何操作。

  1. With语句是什么?
  2. 有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式。一个很好的例子是文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。
  3. Without the with statement, one would write something along the lines of:
  4. 如果不用with语句,代码如下:

  5. file = open("/tmp/foo.txt")
  6. data = file.read()
  7. file.close()
  8.  这里有两个问题。一是可能忘记关闭文件句柄;二是文件读取数据发生异常,没有进行任何处理。下面是处理异常的加强版本:

  9. file = open("/tmp/foo.txt")
  10. try:
  11.     data = file.read()
  12. finally:
  13.     file.close()
  14. 虽然这段代码运行良好,但是太冗长了。这时候就是with一展身手的时候了。除了有更优雅的语法,with还可以很好的处理上下文环境产生的异常。下面是with版本的代码:

  15. with open("/tmp/foo.txt") as file:
  16.     data = file.read()
  17.     
  18. with如何工作?
  19. 这看起来充满魔法,但不仅仅是魔法,Python对with的处理还很聪明。基本思想是with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。
  20. 紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。
  21. 下面例子可以具体说明with如何工作:

  22. #!/usr/bin/env python
  23. # with_example01.py
  24.  
  25.  
  26. class Sample:
  27.     def __enter__(self):
  28.         print "In __enter__()"
  29.         return "Foo"
  30.  
  31.     def __exit__(self, type, value, trace):
  32.         print "In __exit__()"
  33.  
  34.  
  35. def get_sample():
  36.     return Sample()
  37.  
  38.  
  39. with get_sample() as sample:
  40.     print "sample:", sample
  41.  运行代码,输出如下

  42. bash-3.2$ ./with_example01.py
  43. In __enter__()
  44. sample: Foo
  45. In __exit__()


阅读(2942) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~