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连接MySQL、MongoDB、Redis、memcache等数据库的方法
Nov 15 Python
Tensorflow 利用tf.contrib.learn建立输入函数的方法
Feb 08 Python
python tkinter界面居中显示的方法
Oct 11 Python
Python I/O与进程的详细讲解
Mar 08 Python
python实现字符串加密成纯数字
Mar 19 Python
使用pyinstaller打包PyQt4程序遇到的问题及解决方法
Jun 24 Python
django页面跳转问题及注意事项
Jul 18 Python
Python处理session的方法整理
Aug 29 Python
Python3标准库之threading进程中管理并发操作方法
Mar 30 Python
简单的Python人脸识别系统
Jul 14 Python
详解pytorch tensor和ndarray转换相关总结
Sep 03 Python
python爬虫框架feapde的使用简介
Apr 20 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 REMOTE_ADDR之获取访客IP的代码
2008/04/22 PHP
Discuz 6.0+ 批量注册用户名
2009/09/13 PHP
php的ddos攻击解决方法
2015/01/08 PHP
PHP获取redis里不存在的6位随机数应用示例【设置24小时过时】
2017/06/07 PHP
thinkPHP框架实现生成条形码的方法示例
2018/06/06 PHP
PHP使用PhpSpreadsheet操作Excel实例详解
2020/03/26 PHP
JS、jquery实现几分钟前、几小时前、几天前等时间差显示效果的代码实例分享
2014/04/11 Javascript
javascript中setInterval的用法
2015/07/19 Javascript
解决jQuery上传插件Uploadify出现Http Error 302错误的方法
2015/12/18 Javascript
深入理解JQuery中的事件与动画
2016/05/18 Javascript
完美解决jQuery符号$与其他javascript 库、框架冲突的问题
2016/08/09 Javascript
什么是JavaScript注入攻击?
2016/09/14 Javascript
Vue.js Ajax动态参数与列表显示实现方法
2016/10/20 Javascript
Bootstrap 3.x打印预览背景色与文字显示异常的解决
2016/11/06 Javascript
vue.js学习笔记:如何加载本地json文件
2017/01/17 Javascript
完美实现js焦点轮播效果(二)(图片可滚动)
2017/03/07 Javascript
浅析Vue实例以及生命周期
2018/08/14 Javascript
深入理解Vue 组件之间传值
2018/08/16 Javascript
Javascript Dom元素获取和添加详解
2019/09/24 Javascript
vue实现微信浏览器左上角返回按钮拦截功能
2020/01/18 Javascript
vue自定义组件实现双向绑定
2021/01/13 Vue.js
在Python的Flask框架下收发电子邮件的教程
2015/04/21 Python
python3实现读取chrome浏览器cookie
2016/06/19 Python
学习Python selenium自动化网页抓取器
2018/01/20 Python
Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能示例
2018/07/18 Python
python2与python3的print及字符串格式化小结
2018/11/30 Python
python TK库简单应用(实时显示子进程输出)
2019/10/29 Python
浅谈tensorflow之内存暴涨问题
2020/02/05 Python
基于pygame实现童年掌机打砖块游戏
2020/02/25 Python
python列表切片和嵌套列表取值操作详解
2020/02/27 Python
Boden澳大利亚官网:英国在线服装公司
2018/08/05 全球购物
优秀员工自荐书
2013/12/19 职场文书
奶茶店创业计划书范文
2014/01/17 职场文书
“向国旗敬礼”活动策划方案(4篇)
2014/09/27 职场文书
2014年大堂经理工作总结
2014/11/21 职场文书
创业计划书之奶茶店开店方案范本!
2019/08/06 职场文书