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之编写类之三子类
Oct 11 Python
简述Python中的进程、线程、协程
Mar 18 Python
Django基础之Model操作步骤(介绍)
May 27 Python
python spyder中读取txt为图片的方法
Apr 27 Python
python 实现倒排索引的方法
Dec 25 Python
django如何通过类视图使用装饰器
Jul 24 Python
Django 迁移、操作数据库的方法
Aug 02 Python
使用 Python 合并多个格式一致的 Excel 文件(推荐)
Dec 09 Python
tensorflow 分类损失函数使用小记
Feb 18 Python
python自动脚本的pyautogui入门学习
Apr 01 Python
python中K-means算法基础知识点
Jan 25 Python
分析Python list操作为什么会错误
Nov 17 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 时间计算问题小结
2009/01/04 PHP
php一行代码获取文件后缀名实例分析
2014/11/12 PHP
详解PHP中的外观模式facade pattern
2018/02/05 PHP
PHP读取Excel内的图片(phpspreadsheet和PHPExcel扩展库)
2019/11/19 PHP
JQuery动态创建DOM、表单元素的实现代码
2011/08/09 Javascript
jQuery学习笔记(4)--Jquery中获取table中某列值的具体思路
2013/04/10 Javascript
jQuery使用toggleClass方法动态添加删除Class样式的方法
2015/03/26 Javascript
微信js-sdk分享功能接口常用逻辑封装示例
2016/10/13 Javascript
Vue.js 插件开发详解
2017/03/29 Javascript
vue与TypeScript集成配置最简教程(推荐)
2017/10/17 Javascript
基于vue中css预加载使用sass的配置方式详解
2018/03/13 Javascript
JavaScript 日期时间选择器一些小结
2018/04/02 Javascript
微信小程序实现富文本图片宽度自适应的方法
2019/01/20 Javascript
利用vue-i18n实现多语言切换效果的方法
2019/06/19 Javascript
七行JSON代码把你的网站变成移动应用过程详解
2019/07/09 Javascript
vue2.0 获取从http接口中获取数据,组件开发,路由配置方式
2019/11/04 Javascript
JQuery事件委托(适用于给动态生成的脚本元素添加事件)
2020/02/01 jQuery
js实现菜单跳转效果
2020/12/11 Javascript
python关键字and和or用法实例
2015/05/28 Python
python 求1-100之间的奇数或者偶数之和的实例
2019/06/11 Python
python开发实例之Python的Twisted框架中Deferred对象的详细用法与实例
2020/03/19 Python
python按顺序重命名文件并分类转移到各个文件夹中的实现代码
2020/07/21 Python
matplotlib 三维图表绘制方法简介
2020/09/20 Python
python 用opencv实现霍夫线变换
2020/11/27 Python
python实现模拟器爬取抖音评论数据的示例代码
2021/01/06 Python
HTML5 Geolocation API的正确使用方法
2018/12/04 HTML / CSS
Zadig&Voltaire官网:法国时装品牌
2018/01/05 全球购物
德国50岁以上交友网站:Lebensfreunde
2020/03/18 全球购物
物业管理计划书
2014/01/10 职场文书
商务邀请函范文
2014/01/14 职场文书
大学生简短的自我评价分享
2014/02/20 职场文书
学校花圃的标语
2014/06/18 职场文书
公司财务管理制度
2015/08/04 职场文书
家庭教育培训学习心得体会
2016/01/14 职场文书
2016年幼儿园万圣节活动总结
2016/04/05 职场文书
Redis中缓存穿透/击穿/雪崩问题和解决方法
2021/12/04 Redis