Python中with及contextlib的用法详解


Posted in Python onJune 08, 2017

本文实例讲述了Python中with及contextlib的用法。分享给大家供大家参考,具体如下:

平常Coding过程中,经常使用到的with场景是(打开文件进行文件处理,然后隐式地执行了文件句柄的关闭,同样适合socket之类的,这些类都提供了对with的支持):

with file('test.py','r') as f :
  print f.readline()

with的作用,类似try...finally...,提供一种上下文机制,要应用with语句的类,其内部必须提供两个内置函数__enter__以及__exit__。前者在主体代码执行前执行,后则在主体代码执行后执行。as后面的变量,是在__enter__函数中返回的。通过下面这个代码片段以及注释说明,可以清晰明白__enter__与__exit__的用法:

#!encoding:utf-8
class echo :
  def output(self) :
    print 'hello world'
  def __enter__(self):
    print 'enter'
    return self #返回自身实例,当然也可以返回任何希望返回的东西
  def __exit__(self, exception_type, exception_value, exception_traceback):
    #若发生异常,会在这里捕捉到,可以进行异常处理
    print 'exit'
    #如果改__exit__可以处理改异常则通过返回True告知该异常不必传播,否则返回False
    if exception_type == ValueError :
      return True
    else:
      return False
with echo() as e:
  e.output()
  print 'do something inside'
print '-----------'
with echo() as e:
  raise ValueError('value error')
print '-----------'
with echo() as e:
  raise Exception('can not detect')

运行结果:

Python中with及contextlib的用法详解

contextlib是为了加强with语句,提供上下文机制的模块,它是通过Generator实现的。通过定义类以及写__enter__和__exit__来进行上下文管理虽然不难,但是很繁琐。contextlib中的contextmanager作为装饰器来提供一种针对函数级别的上下文管理机制。常用框架如下:

from contextlib import contextmanager
@contextmanager
def make_context() :
  print 'enter'
  try :
    yield {}
  except RuntimeError, err :
    print 'error' , err
  finally :
    print 'exit'
with make_context() as value :
  print value

contextlib还有连个重要的东西,一个是nested,一个是closing,前者用于创建嵌套的上下文,后则用于帮你执行定义好的close函数。但是nested已经过时了,因为with已经可以通过多个上下文的直接嵌套了。下面是一个例子:

from contextlib import contextmanager
from contextlib import nested
from contextlib import closing
@contextmanager
def make_context(name) :
  print 'enter', name
  yield name
  print 'exit', name
with nested(make_context('A'), make_context('B')) as (a, b) :
  print a
  print b
with make_context('A') as a, make_context('B') as b :
  print a
  print b
class Door(object) :
  def open(self) :
    print 'Door is opened'
  def close(self) :
    print 'Door is closed'
with closing(Door()) as door :
  door.open()

运行结果:

Python中with及contextlib的用法详解

总结:python有很多强大的特性,由于我们平常总习惯于之前C++或java的一些编程习惯,时常忽略这些好的机制。因此,要学会使用这些python特性,让我们写的python程序更像是python。

更多关于Python相关内容可查看本站专题:《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python回溯法实现数组全排列输出实例分析
Mar 17 Python
python在windows和linux下获得本机本地ip地址方法小结
Mar 20 Python
Python自定义scrapy中间模块避免重复采集的方法
Apr 07 Python
python实现中文转换url编码的方法
Jun 14 Python
Python实现读取文件最后n行的方法
Feb 23 Python
Python生成8位随机字符串的方法分析
Dec 05 Python
Python使用gRPC传输协议教程
Oct 16 Python
python 搜索大文件的实例代码
Jul 08 Python
解决python 3 urllib 没有 urlencode 属性的问题
Aug 22 Python
python+requests接口压力测试500次,查看响应时间的实例
Apr 30 Python
使用pyplot.matshow()函数添加绘图标题
Jun 16 Python
使paramiko库执行命令时在给定的时间强制退出功能的实现
Mar 03 Python
Python使用pylab库实现画线功能的方法详解
Jun 08 #Python
Python实现对象转换为xml的方法示例
Jun 08 #Python
Python实现的手机号归属地相关信息查询功能示例
Jun 08 #Python
python用pickle模块实现“增删改查”的简易功能
Jun 07 #Python
Python3 socket同步通信简单示例
Jun 07 #Python
Python实现获取磁盘剩余空间的2种方法
Jun 07 #Python
Python2.7基于淘宝接口获取IP地址所在地理位置的方法【测试可用】
Jun 07 #Python
You might like
PHP+FFMPEG实现将视频自动转码成H264标准Mp4文件
2014/09/24 PHP
php利用反射实现插件机制的方法
2015/03/14 PHP
PHP入门教程之字符串处理技巧总结(转换,过滤,解析,查找,截取,替换等)
2016/09/11 PHP
jquery的冒泡事件的阻止与允许(三种实现方法)
2013/02/01 Javascript
几种设置表单元素中文本输入框不可编辑的方法总结
2013/11/25 Javascript
jquery自动将form表单封装成json的具体实现
2014/03/17 Javascript
封装了一个支持匿名函数的Javascript事件监听器
2014/06/05 Javascript
javascript显示上周、上个月日期的处理方法
2016/02/03 Javascript
JS实现根据文件字节数返回文件大小的方法
2016/08/02 Javascript
web前端开发upload上传头像js示例代码
2016/10/22 Javascript
js实现滑动到页面底部自动加载更多功能
2017/02/15 Javascript
微信小程序中post方法与get方法的封装
2017/09/26 Javascript
js 索引下标之li集合绑定点击事件
2018/01/12 Javascript
送你43道JS面试题(收藏)
2019/06/17 Javascript
原生js实现抽奖小游戏
2019/06/27 Javascript
layui添加动态菜单与选项卡
2019/07/26 Javascript
微信小程序swiper左右扩展各显示一半代码实例
2019/12/05 Javascript
通过vue刷新左侧菜单栏操作
2020/08/06 Javascript
vue中echarts的用法及与elementui-select的协同绑定操作
2020/11/17 Vue.js
Vue 打包的静态文件不能直接运行的原因及解决办法
2020/11/19 Vue.js
[01:11:48]Fnatic vs IG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
[56:38]DOTA2-DPC中国联赛正赛Aster vs Magma BO3 第一场 3月5日
2021/03/11 DOTA
numpy中的ndarray方法和属性详解
2019/05/27 Python
Python decimal模块使用方法详解
2020/06/08 Python
Python实现Canny及Hough算法代码实例解析
2020/08/06 Python
如何基于Python pygame实现动画跑马灯
2020/11/18 Python
中国专业的综合网上购物商城:京东
2016/08/02 全球购物
超市5.1促销活动
2014/01/15 职场文书
留学推荐信中文范文三篇
2014/01/25 职场文书
《狼和小羊》教学反思
2014/04/20 职场文书
中学综治宣传月活动总结
2015/05/07 职场文书
平凡的世界读书笔记
2015/06/25 职场文书
Python类方法总结讲解
2021/07/26 Python
php去除deprecated的实例方法
2021/11/17 PHP
基于Python编写一个监控CPU的应用系统
2022/06/25 Python
CSS 实现角标效果的完整代码
2022/06/28 HTML / CSS