- 浏览: 27304 次
- 性别:
- 来自: 北京
最新评论
Judging from comp.lang.python and other forums, Python 2.5’s new with statement seems to be a bit confusing even for experienced Python programmers.
As most other things in Python, the with statement is actually very simple, once you understand the problem it’s trying to solve. Consider this piece of code:
Here, “set things up” could be opening a file, or acquiring some sort of external resource, and “tear things down” would then be closing the file, or releasing or removing the resource. The try-finally construct guarantees that the “tear things down” part is always executed, even if the code that does the work doesn’t finish.
If you do this a lot, it would be quite convenient if you could put the “set things up” and “tear things down” code in a library function, to make it easy to reuse. You can of course do something like
But that’s a bit verbose, especially if you need to modify local variables. Another approach is to use a one-shot generator, and use the for-in statement to “wrap” the code:
But yield isn’t even allowed inside a try-finally in 2.4 and earlier. And while that could be fixed (and it has been fixed in 2.5), it’s still a bit weird to use a loop construct when you know that you only want to execute something once.
So after contemplating a number of alternatives, GvR and the python-dev team finally came up with a generalization of the latter, using an object instead of a generator to control the behaviour of an external piece of code:
Now, when the “with” statement is executed, Python evaluates the expression, calls the __enter__ method on the resulting value (which is called a “context guard”), and assigns whatever __enter__ returns to the variable given by as. Python will then execute the code body, and no matter what happens in that code, call the guard object’s __exit__ method.
As an extra bonus, the __exit__ method can look at the exception, if any, and suppress it or act on it as necessary. To suppress the exception, just return a true value. For example, the following __exit__ method swallows any TypeError, but lets all other exceptions through:
In Python 2.5, the file object has been equipped with __enter__ and __exit__ methods; the former simply returns the file object itself, and the latter closes the file:
>>> f = open("x.txt")
>>> f
<open file 'x.txt', mode 'r' at 0x00AE82F0>
>>> f.__enter__()
<open file 'x.txt', mode 'r' at 0x00AE82F0>
>>> f.read(1)
'X'
>>> f.__exit__(None, None, None)
>>> f.read(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file
so to open a file, process its contents, and make sure to close it, you can simply do:
This wasn’t very difficult, was it?
[comment on/vote for this article]
Fredrik Lundh | October 2006 | Originally posted to online.effbot.org
http://effbot.org/zone/python-with-statement.htm
As most other things in Python, the with statement is actually very simple, once you understand the problem it’s trying to solve. Consider this piece of code:
set things up try: do something finally: tear things down
Here, “set things up” could be opening a file, or acquiring some sort of external resource, and “tear things down” would then be closing the file, or releasing or removing the resource. The try-finally construct guarantees that the “tear things down” part is always executed, even if the code that does the work doesn’t finish.
If you do this a lot, it would be quite convenient if you could put the “set things up” and “tear things down” code in a library function, to make it easy to reuse. You can of course do something like
def controlled_execution(callback): set things up try: callback(thing) finally: tear things down def my_function(thing): do something controlled_execution(my_function)
But that’s a bit verbose, especially if you need to modify local variables. Another approach is to use a one-shot generator, and use the for-in statement to “wrap” the code:
def controlled_execution(): set things up try: yield thing finally: tear things down for thing in controlled_execution(): do something with thing
But yield isn’t even allowed inside a try-finally in 2.4 and earlier. And while that could be fixed (and it has been fixed in 2.5), it’s still a bit weird to use a loop construct when you know that you only want to execute something once.
So after contemplating a number of alternatives, GvR and the python-dev team finally came up with a generalization of the latter, using an object instead of a generator to control the behaviour of an external piece of code:
class controlled_execution: def __enter__(self): set things up return thing def __exit__(self, type, value, traceback): tear things down with controlled_execution() as thing: some code
Now, when the “with” statement is executed, Python evaluates the expression, calls the __enter__ method on the resulting value (which is called a “context guard”), and assigns whatever __enter__ returns to the variable given by as. Python will then execute the code body, and no matter what happens in that code, call the guard object’s __exit__ method.
As an extra bonus, the __exit__ method can look at the exception, if any, and suppress it or act on it as necessary. To suppress the exception, just return a true value. For example, the following __exit__ method swallows any TypeError, but lets all other exceptions through:
def __exit__(self, type, value, traceback): return isinstance(value, TypeError)
In Python 2.5, the file object has been equipped with __enter__ and __exit__ methods; the former simply returns the file object itself, and the latter closes the file:
>>> f = open("x.txt")
>>> f
<open file 'x.txt', mode 'r' at 0x00AE82F0>
>>> f.__enter__()
<open file 'x.txt', mode 'r' at 0x00AE82F0>
>>> f.read(1)
'X'
>>> f.__exit__(None, None, None)
>>> f.read(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file
so to open a file, process its contents, and make sure to close it, you can simply do:
with open("x.txt") as f: data = f.read() do something with data
This wasn’t very difficult, was it?
[comment on/vote for this article]
Fredrik Lundh | October 2006 | Originally posted to online.effbot.org
http://effbot.org/zone/python-with-statement.htm
发表评论
-
python 性能测试(1)-- % vs + vs str.join vs +=
2013-01-15 09:48 1383网上广为流传着"不要使用+" 连接字符串的 ... -
wxpython如何查看某些控件发什么样的命令
2013-01-14 18:15 1448大家知道一些控件Button, List,Checkbox,S ... -
python 当中类的实例也能当函数使?靠__call__!(
2013-01-15 09:48 844python当中的一个class A的实例a1,经常看到有的源 ... -
a py to delete the trailling spaces and replace the "\t" with 4 spaces
2013-01-14 18:17 757#author: 54yuri import os i ... -
Python的lambda函数与排序
2013-01-14 18:16 2295Python的lambda函数与排序 2008-06-19 2 ... -
python把帮助导出到文件当中
2013-01-14 18:16 1182有时候在python 当中使用 import xxx ... -
自定义的模块下一定要加__init__.py , 否则当成普通目录来处理
2013-01-14 18:15 779一工程,结构如下 ├─MyProject ├─MyMo ... -
Python 当中逗号的一处用法
2013-01-13 19:17 1033曾经看到代码当中有一段颇为奇怪,是 b = 111 a = ... -
python的GUI设计理念,被震撼住了
2013-01-13 19:17 5482今天看到(2011-06-18)今天看到一句话,太给力了,给人 ... -
【转帖+改造】django HTTP Request 的调用层次
2013-01-13 19:16 1008from http://kasicass.blog.163.c ... -
【转帖】利用decorator实现Django表单防重复提交
2013-01-12 17:53 2089背景: 我的用例中不可出现重复的记录,如:下订单,用户填 ... -
virtualenv virtualenvwrapper python 多版本 多环境切换
2013-01-12 17:42 3095virtualenv是一个python工具. 它可以创建一个独 ... -
python 性能优化当中的几个谬误(1) -- 不要使用'+=' ?
2013-01-12 16:51 26网上广为流传着"不要使用+=" 连接字符串 ...
相关推荐
Maya Programming with Python Cookbook MayaPythonForGamesAndFilm Prentice.Hall.Rapid.GUI.Programming.with.Python.and.Qt.Oct.2007 Robert Galanakis - Practical Maya Programming with Python - 2014
论坛转帖工具 .......... 纯HTML
一键转帖 一键8经验签到. 绿易贴吧工具3.7 11.11版.rar
编辑人员转帖去水印工具,很好用,直接选中水印区域后运行伪装即可!
转帖性能测试
UBB论坛转帖圣手.exeUBB论坛转帖圣手.exe
discuz X2转帖工具、采集工具,discuz论坛批量发帖,批量转帖工具
这是一个世界编程大赛第一名写的程序,很好玩的,大家试试看。
1.修改自Convert X转帖工具 2.新增批量替换关键词(原来是单个词语替换,可以利用这个功能删除一些网站的防转帖代码) 3.批量随机新增文字(新增内容可自定义,从而实现伪原创) 4.cookie记录替换和新增关键词(避免每次...
Html2UBBMaxcj_Softii论坛专用转帖工具
转帖图片提取工具可以对论坛图片附件信息进行清除,只保留图片代码,操作很简单,推荐有需要转帖图片工具的朋友下载 转帖图片提取工具使用方法: 将IP138上处理过的东西复制到上方的编辑框内,点击只要图片,下面...
gl8雨刮维修以及调试转帖.doc
转帖PLCDCSFCS三大控制系统的特点和差异.doc
关于工作与生活的转帖 一篇论述精辟的文章,值得一看。
用PHP批量生成图片缩略图——活跃论坛转帖
看到论坛里帖子由精美的图片想转过来,或者批量提取地址时很好用
转发至人人网" charset="400-03-7" id="s_renren" href="http://share.renren.com/share/buttonshare.do?link=http://www.ttup.me" target="_blank"><img src="images/分享到人人网.jpg" /> 分数可能有点高,这个和...
轻松转帖之突破网页复制限制宣贯.pdf
股票T+0的操作(转帖).pdf