Python之with语句

在Python中,我们在打开文件的时候,为了代码的健壮性,通常要考虑一些异常情况,比如:

try:ccfile = open('/path/data')content = ccfile.readlines()ccfile.close()except IOError:log.write('no data read\n')

我们将真正干活的代码扔到try语句块中,如果文件操作出现异常,则写一条错误日志;

考虑一种情况,如果文件打开成功,但readlines()调用失败,异常处理会立即跳转到except处执行,这样文件关闭就没有机会被执行到了。

一种解决办法就是将close()语句放到finally子句中去,finally的特点是不管有无异常,都会被执行到。

try:try:ccfile = open('/path/data')content = ccfile.readlines()except IOError:log.write('no data read\n')finallyccfile.close()

finally的另一种可选的风格:

try:try:ccfile = open('/path/data')content = ccfile.readlines()finally IOError:ccfile.close()except IOError:log.write('no data read\n')

如上所述的标准化的 try-except和try-finally 的用法是保证资源的分配和回收,比如文件(数据、日志、数据库等等)、线程资源、数据库连接等,但它们书写起来却不够优雅。with语句的目的在于从流程图中把try、except、 finally关键字和资源分配、释放相关代码统统去掉,

with处理文件操作的一个实例:

with open('/etc/passwd') as f:for line in f:print(line)

这段代码的作用:打开一个文件,如果一切正常,把文件对象赋值给f,然后用迭代器遍历文件中每一行,当完成时,关闭文件;而无论在这段代码的任何地方,如果发生异常,此时文件仍会被关闭。

with看起来如此简单,但是其背后还有一些工作要做,因为你不能对Python的任意符号使用with语句,它仅能工作于支持上下文管理协议(context management protocol)的对象。也就是说,只有内建了“上下文管理”的对象可以和with一起工作,目前支持该协议的对象有:

  • file
  • decimal.Context
  • thread.LockType
  • threading.Lock
  • threading.RLock
  • threading.Condition
  • threading.Semaphore
  • threading.BoundedSemaphore

现在来看with的语法:

with context_expr as var:with_suite

当with语句执行时,便执行上下文表达式(context_expr)来获得一个上下文管理器,上下文管理器的职责是提供一个上下文对象,用于在with语句块中处理细节:

一旦获得了上下文对象,就会调用它的__enter__()方法,将完成with语句块执行前的所有准备工作,如果with语句后面跟了as语句,则用__enter__()方法的返回值来赋值;

当with语句块结束时,无论是正常结束,还是由于异常,都会调用上下文对象的__exit__()方法,__exit__()方法有3个参数,如果with语句正常结束,三个参数全部都是 None;如果发生异常,三个参数的值分别等于调用sys.exc_info()函数返回的三个值:类型(异常类)、值(异常实例)和跟踪记录(traceback),相应的跟踪记录对象。

因为上下文管理器主要作用于共享资源,__enter__()和__exit__()方法基本是干的需要分配和释放资源的低层次工作,比如:数据库连接、锁分配、信号量加/减、状态管理、文件打开/关闭、异常处理等。

现在,我们可以在自定义类里面创建__enter__()和__exit__()方法,这样就可以配合with语句创建类实例了:

class A:  def __enter__(self):  print '__enter__() called'def __exit__(self, e_t, e_v, t_b):  print '__exit__() called'with A() as a:print('got instance')

可以看到输出为:

__enter__() called
got instance
__exit__() called

另外python库中还有一个模块contextlib,使你不用构造含有__enter__, __exit__的类就可以使用with:

from __future__ import with_statement
from contextlib import contextmanager  @contextmanager
def context():print 'entering the zone'try:yieldexcept Exception, e:  print 'with an error %s'%eraise eelse:print 'with no error'  with context():  print '----in context call------' 

参考文档:

http://www.ibm.com/developerworks/cn/opensource/os-cn-pythonwith/

转载于:https://www.cnblogs.com/chenny7/p/4213447.html

Python之with语句相关推荐

  1. Python: 没有switch-case语句

    初学Python语言,竟然很久才发现Python没有switch-case语句 官方的解释说,"用if... elif... elif... else序列很容易来实现 switch / ca ...

  2. python基础常用语句-python爬虫之python一条语句分析几个常用函数和概念

    https://www.xin3721.com/eschool/pythonxin3721/ 前言 过年也没完全闲着,每天用一点点时间学点东西,本文为大家介绍几个python操作的细节,包含all.a ...

  3. python基本语法语句-Python基本语句

    一.Python 条件语句 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 可以通过下图来简单了解条件语句的执行过程: Python程序语言指定任何非 ...

  4. python基本语法语句-python基本语句有哪些

    Python是一种计算机程序设计语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大型项目的开发.下面我们就为 ...

  5. python while循环语句-Python While 循环语句

    Python While 循环语句 Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务.其基本形式为: while 判断条件(cond ...

  6. python编程if语法-python if控制流语句 语法笔记

    Python程序是由很多语句组成,python if执行条件语句也是其中的一种,也是本文要讲的重点.python if语句用于控制条件代码的执行,else和elif也是同样的功能,通常和for循环语句 ...

  7. python while循环语句-python while循环控制流语句结构与用法

    python while循环语句和for语句都是python的主要循环结构.while语句是python中最通用的迭代结构,也是一个条件循环语句.while与if语句有哪些不同,标准语法结构及循环使用 ...

  8. python语言if语句-Python2 if 条件语句

    程序在一般情况下是按顺序执行的,就像流水账一样,一条一条顺序运行 当然,有时候我们需要根据条件来有选择的执行某些语句,或者重复执行某些语句 Python 提供了各种控制结构,允许更复杂的执行路径 条件 ...

  9. python的用途实例-python中pass语句意义与作用(实例分析)

    想必大家都是刚刚才开始接触python这门语言的,今天这篇文章就来带大家来了解一下python这门语言之中常常会用到的一个语句pass语句.想必大家都很好奇python中pass作用是什么,接下来我就 ...

  10. Python if控制流语句

    #!/usr/bin/env python # -*- coding:utf-8 -*-# Python if控制流语句 letter = input("please input:" ...

最新文章

  1. 一篇文章带你详解 TCP/IP 协议(下)
  2. Windows进程与线程学习笔记(九)—— 线程优先级/进程挂靠/跨进程读写
  3. Qt小游戏《2048》源码(含大量注释)
  4. abstract类_012 JAVA 抽象类、接口、String类的基础了解
  5. 复制SQLSERVER数据库文件
  6. P4310-绝世好题【位运算,dp】
  7. 网站开发中很有用的几个 jQuery 地图插件
  8. 程序员!别逼自己刷题了!每天花10分钟做这件事,编程能力暴增!
  9. 【iOS开发】理解 IBOutlet 和 IBAction
  10. Python爬虫从入门到精通:(14)验证码识别_Python涛哥
  11. 赛尔号桌面版_赛尔号手游电脑版
  12. 天涯明月刀测试-bug
  13. 中级软件设计师刷题笔记
  14. 超有用:记一次Yapi上传报错及其处理方式
  15. 黑客组织Anonymous(匿名者)
  16. UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xb5 in position 2: invalid start byte
  17. Windows下安装VMware
  18. VTM3.0代码阅读:xEstimateMvPredAMVP函数
  19. Excel 给一列数据前批量添加字符
  20. jaeger 是很么软件_开源分布式跟踪系统Jaeger介绍 (六步快速上手)

热门文章

  1. ZOJ-2575 Full of Painting 动态规划
  2. 【掩耳盗铃】[转载]北京铁路局:“北京站37号窗口售票员内部大量出票”是为分区售票...
  3. SplitContainer.SplitterDistance属性值设置应注意的与FixedPanel有关
  4. python替换UTF-8编码文本中任意特殊字符,包括中文符号问题:大量文本,将其中的特殊字符用空
  5. L1-078 吉老师的回归 (15 分)-PAT 团体程序设计天梯赛 GPLT
  6. CCCC-GPLT L3-013. 非常弹的球 团体程序设计天梯赛
  7. 星低级格式化工具_Elixir 数据库查询工具 Ecto 讲解
  8. 【自动化测试】在做自动化测试之前你需要知道的
  9. showModalDialog模态对话框的使用详解以及浏览器兼容
  10. Angular项目构建指南 - 不再为angular构建而犹豫不决