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计算N天之后日期的方法
Mar 31 Python
深入理解python中的select模块
Apr 23 Python
解决Python2.7读写文件中的中文乱码问题
Apr 12 Python
Python 类的特殊成员解析
Jun 20 Python
python3利用ctypes传入一个字符串类型的列表方法
Feb 12 Python
原生python实现knn分类算法
Oct 24 Python
Python Handler处理器和自定义Opener原理详解
Mar 05 Python
Python利用for循环打印星号三角形的案例
Apr 12 Python
Python列表去重复项的N种方法(实例代码)
May 12 Python
使用PyWeChatSpy自动回复微信拍一拍功能的实现代码
Jul 02 Python
详解python模块pychartdir安装及导入问题
Oct 22 Python
python Django框架快速入门教程(后台管理)
Jul 21 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
重置版战役片段
2020/04/09 魔兽争霸
SESSION信息保存在哪个文件目录下以及能够用来保存什么类型的数据
2012/06/17 PHP
CodeIgniter中实现泛域名解析
2014/07/19 PHP
ThinkPHP5+UEditor图片上传到阿里云对象存储OSS功能示例
2019/08/05 PHP
Laravel 5.5 异常处理 & 错误日志的解决
2019/10/17 PHP
JavaScript RegExp方法获取地址栏参数(面向对象)
2009/03/10 Javascript
Jquery getJSON方法详细分析
2013/12/26 Javascript
浅析js预加载/延迟加载
2014/09/25 Javascript
jQuery使用Selectator插件实现多选下拉列表过滤框(附源码下载)
2016/04/08 Javascript
源码分析Vue.js的监听实现教程
2017/04/23 Javascript
浅谈sass在vue注意的地方
2017/08/10 Javascript
JS中通过url动态获取图片大小的方法小结(两种方法)
2018/10/31 Javascript
5分钟快速看懂ES6中的反射与代理
2019/12/19 Javascript
js校验开始时间和结束时间
2020/05/26 Javascript
Javascript表单序列化原理及实现代码详解
2020/10/30 Javascript
[03:57]DOTA2英雄梦之声_第03期_幻影刺客
2014/06/21 DOTA
Python中用函数作为返回值和实现闭包的教程
2015/04/27 Python
详解python开发环境搭建
2016/12/16 Python
python 对dataframe下面的值进行大规模赋值方法
2018/06/09 Python
python set内置函数的具体使用
2019/07/02 Python
python3使用Pillow、tesseract-ocr与pytesseract模块的图片识别的方法
2020/02/26 Python
PyCharm MySQL可视化Database配置过程图解
2020/06/09 Python
世界上最大的网络主机公司:1&1
2016/10/12 全球购物
Ever New加拿大官网:彰显女性美
2018/10/05 全球购物
意大利婴儿产品网上商店:Mukako
2018/10/14 全球购物
构造器Constructor是否可被override?
2013/08/06 面试题
电气个人求职信范文
2014/02/04 职场文书
房屋委托书范本
2014/04/04 职场文书
幼儿园辞职书
2015/02/26 职场文书
继续教育个人总结
2015/03/03 职场文书
大学生就业指导课心得体会
2016/01/15 职场文书
《圆的周长》教学反思
2016/02/17 职场文书
《曾国藩家书》读后感——读家书,立家风
2019/08/21 职场文书
解决jupyter notebook图片显示模糊和保存清晰图片的操作
2021/04/24 Python
Python OpenCV 彩色与灰度图像的转换实现
2021/06/05 Python
Android开发之底部导航栏的快速实现
2022/04/28 Java/Android