with 语句是在 Python 2.5 版本引入的,从 2.6 版本开始成为缺省的功能。with 语句作为 try/finally 编码范式的一种替代,用于对资源访问进行控制的场合。本章对 with 语句进行介绍,包括 with 语句的基本语法和工作原理,自定义支持 with 语句的类,以及使用 contextlib 工具加入对 with 语句的支持,使读者更好的了解和使用 with 语句。

with 语句是从 Python 2.5 开始引入的一种与异常处理相关的功能(2.5 版本中要通过 from __future__ import with_statement 导入后才可以使用),从 2.6 版本开始缺省可用(参考 What's new in Python 2.6? 中 with 语句相关部分介绍)。with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。

术语

要使用 with 语句,首先要明白上下文管理器这一概念。有了上下文管理器,with 语句才能工作。

下面是一组与上下文管理器和with 语句有关的概念。

上下文管理协议(Context Management Protocol):包含方法 __enter__() 和 __exit__(),支持

该协议的对象要实现这两个方法。

上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了

__enter__() 和 __exit__() 方法。上下文管理器定义执行 with 语句时要建立的运行时上下文,

负责执行 with 语句块上下文中的进入与退出操作。通常使用 with 语句调用上下文管理器,

也可以通过直接调用其方法来使用。

运行时上下文(runtime context):由上下文管理器创建,通过上下文管理器的 __enter__() 和

__exit__() 方法实现,__enter__() 方法在语句体执行之前进入运行时上下文,__exit__() 在

语句体执行完后从运行时上下文退出。with 语句支持运行时上下文这一概念。

上下文表达式(Context Expression):with 语句中跟在关键字 with 之后的表达式,该表达式

要返回一个上下文管理器对象。

语句体(with-body):with 语句包裹起来的代码块,在执行语句体之前会调用上下文管

理器的 __enter__() 方法,执行完语句体之后会执行 __exit__() 方法。

其实说白了就是,类进入,创建对象和类退出,销毁对象。

基本语法和工作原理

with 语句的语法格式如下:

清单 1. with 语句的语法格式
    with context_expression [as target(s)]:
with-body

这里 context_expression 要返回一个上下文管理器对象,该对象并不赋值给 as 子句中的 target(s) ,如果指定了 as 子句的话,会将上下文管理器的 __enter__() 方法的返回值赋值给 target(s)。target(s) 可以是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)。

Python 对一些内建对象进行改进,加入了对上下文管理器的支持,可以用于 with 语句中,比如可以自动关闭文件、线程锁的自动获取和释放等。假设要对一个文件进行操作,使用 with 语句可以有如下代码:

清单 2. 使用 with 语句操作文件对象
    with open(r'somefileName') as somefile:
for line in somefile:
print line
# ...more code

这里使用了 with 语句,不管在处理文件过程中是否发生异常,都能保证 with 语句执行完毕后已经关闭了打开的文件句柄。如果使用传统的 try/finally 范式,则要使用类似如下代码:

清单 3. try/finally 方式操作文件对象
    somefile = open(r'somefileName')
try:
for line in somefile:
print line
# ...more code
finally:
somefile.close()

比较起来,使用 with 语句可以减少编码量。已经加入对上下文管理协议支持的还有模块 threading、decimal 等。

详细参见:http://www.ibm.com/developerworks/cn/opensource/os-cn-pythonwith/

浅谈 Python 的 with 语句的更多相关文章

  1. 浅谈 Python 的 with 语句(转)

    add by zhj: 上下文管理器是对try-except-finally的再封装而已,只能算是优化代码这一级别的feature 原文:http://www.ibm.com/developerwor ...

  2. 浅谈 Python 的 with 语句 【转载】

    引言 with 语句是从 Python 2.5 开始引入的一种与异常处理相关的功能(2.5 版本中要通过 from __future__ import with_statement 导入后才可以使用) ...

  3. 浅谈Python在信息学竞赛中的运用及Python的基本用法

    浅谈Python在信息学竞赛中的运用及Python的基本用法 前言 众所周知,Python是一种非常实用的语言.但是由于其运算时的低效和解释型编译,在信息学竞赛中并不用于完成算法程序.但正如LRJ在& ...

  4. 浅谈Python时间模块

    浅谈Python时间模块 今天简单总结了一下Python处理时间和日期方面的模块,主要就是datetime.time.calendar三个模块的使用.希望这篇文章对于学习Python的朋友们有所帮助 ...

  5. 浅谈python字符串存储形式

    http://blog.csdn.net/zhonghuan1992 钟桓 2014年8月31日 浅谈python字符串存储形式 记录一下自己今的天发现疑问而且给出自己现有知识有的回答. 长话短说,用 ...

  6. 开发技术--浅谈Python函数

    开发|浅谈Python函数 函数在实际使用中有很多不一样的小九九,我将从最基础的函数内容,延伸出函数的高级用法.此文非科普片~~ 前言 目前所有的文章思想格式都是:知识+情感. 知识:对于所有的知识点 ...

  7. 开发技术--浅谈python数据类型

    开发|浅谈python数据类型 在回顾Python基础的时候,遇到最大的问题就是内容很多,而我的目的是回顾自己之前学习的内容,进行相应的总结,所以我就不玩基础了,很多在我实际生活中使用的东西,我会在文 ...

  8. 开发技术--浅谈python基础知识

    开发|浅谈python基础知识 最近复习一些基础内容,故将Python的基础进行了总结.注意:这篇文章只列出来我觉得重点,并且需要记忆的知识. 前言 目前所有的文章思想格式都是:知识+情感. 知识:对 ...

  9. [转]浅谈Python web框架

    说到web framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界,各种micro-framework.framework不可胜数,不完全列表见:http://wi ...

随机推荐

  1. oracle 导出数据和导入数据

    导出数据 exp zl_gj/zlkj@gqxt  grants=y tables=(zl_gj.ckgj,zl_gj.gjlx,zl_gj.rkgj) file=c:\gj.dmp log=c:\g ...

  2. jQuery.serializeArray() 函数详解

    serializeArray()函数用于序列化一组表单元素,将表单内容编码为一个JavaScript数组. serializeArray()函数常用于将表单内容序列化为JSON对象,以便于被编码为JS ...

  3. 基于jquery中children()与find()的区别介绍

    本篇文章介绍了,基于jquery中children()与find()的区别,需要的朋友参考下 .children(selector) 方法是返回匹配元素集合中每个元素的所有子元素(仅儿子辈).参数可选 ...

  4. DIV中TABLE居的2种方式

    <html><head><title>测试页面</title></head><body><div width=" ...

  5. [转载]HTML5 Audio/Video 标签,属性,方法,事件汇总

    <audio> 标签属性: src:音乐的URL preload:预加载 autoplay:自动播放 loop:循环播放 controls:浏览器自带的控制条 <audio id=& ...

  6. LA 4731

    dp[i][j]意思是前i个分成j组最小的花费 #include<cstdio> #include<algorithm> #include<cstring> #in ...

  7. uva 10271

    DP  状态转移方程 dp[i][j] = min(dp[i-1][j], dp[i-2][j-1] + w)) dp[i][j] 指的是前i个筷子组成j组所花费的最小值 考虑第i个筷子是否参与第j组 ...

  8. codeforces #309 div1 C

    首先我们会发现所有的人构成了一个图 定义相爱为 在一个集合里 定义相恨为 不在一个集合里 很容易发现满足条件的图一定是一个二分图 那么分类讨论如下: 1.如果出现不合法 答案为0 2.如果不是一个二分 ...

  9. cocos2d-x3.9 默认是 gnustl_static 配置,但是 这个库缺少c++的基础功能... c++_static 功能全面些

    最近的升级Cocos2d-x 3.2正式版.iOS不管是什么程序编译问题,使用结果cocos compile -p android编译APK计划.结果悲剧,出现以下错误. Android NDK: I ...

  10. Android:控件布局(绝对布局)AbsoluteLayout

    绝对布局也叫坐标布局,指定元素的绝对位置,因为适应性很差,一般很少用到.可以使用RelativeLayout替代. 常用属性: android:layout_x  --------组件x坐标 andr ...