上下文管理器

  一直对python中的上下文管理比较迷惑,趁着今天研究SQLAlchemy顺便看了一下,感觉稍微清楚了一点。http://www.cnblogs.com/chenny7/p/4213447.html参考了这篇文章。

  所谓上下文,在函数式编程这个具体的场景中来说,可以理解为和闭包有些类似的一种东西。比如在闭包和装饰器那篇文章中我提到过利用自定义一个装饰器来得到一个加强版的函数。为什么它能够得到加强,就是因为在执行这个函数时,解释器会自动执行一些装饰器中定义的操作。而回到上下文这个话题,很常见的一个例子就是用with语句来打开文件:

with open("test.txt","w") as fi:
fi.write("hello,world")

  相比于传统的文件读写方式,利用with语句来管理上下文的方法做这件事更加省心,我们不用手动地fi.close()了,当with语句块中执行出错也不要紧,fi还是会被close的。那么with语句到底干了点什么事?

  在回答这个问题之前,首先要明确with语句后面跟的对象并不是什么都行,这个对象应该要能支持上下文管理协议。换言之,这个对象应该实现了上下文管理器。就像我们说一个对象是迭代器的话就是说它实现了__iter__方法和next方法一样,可以在with后面正常工作的对象需要实现了__enter__以及__exit__方法。

  这两个方法顾名思义,就是分别指在进入with语句执行之前和结束with语句块执行之后执行的一些操作。基于这样的一种想法,我们就可以自己创建一个可以和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

  值得注意的是__exit__()方法有三个参数,当with语句块中所有语句都正常结束没有出现错误或者异常时这三个参数都是None地进入__exit__方法,但是如果出错了,那么这三个参数就依次是sys.exc_info()得到的三个值,分别是异常类(exc_type)、异常实例(exc_value)和跟踪记录(traceback)。

  

■  关于contextlib

  有时候我们仅仅需要一个针对函数的上下文管理器,并不想写一个新类来实现上下文的管理,这时候可以用contextlib这个内建的库。与其说是一个库,其实我们主要用了这个库中的contextmanager这个装饰器函数:

from contextlib import contextmanager

@contextmanager
def context():
print 'entering the zone'
try:
yield
print "after with"
except Exception, e:
print 'with an error %s'%e
raise e
else:
print 'with no error' with context() as c:
print c
print '----in with call------'

  在import 了 contextmanager之后,用@contextmanager的方式来把我们的函数装饰起来。我们的函数(在这里当然就是context())应该是一个生成器函数,再接受装饰之后它就可以被放到with语句后面,作为一个上下文管理器来管理with语句块中的语句。

  执行顺序是这样的:首先进入context函数开始执行,直至碰到第一个yield语句,把yield得到的对象返回赋值给value变量。然后开始执行with语句块中的语句,执行完成之后,回到context函数中yield的位置继续向下执行。如果在执行with语句块的时候出现了任何异常,那么异常会被传递到context中的except语句块中进行异常处理。

  所以,上述代码执行的结果是:

entering the zone
None
----in with call------
after with
with no error

【Python】 上下文管理器和contextlib的更多相关文章

  1. Python 上下文管理器模块--contextlib

    在 Python 处理文件的时候我们使用 with 关键词来进行文件的资源关闭,但是并不是只有文件操作才能使用 with 语句.今天就让我们一起学习 Python 中的上下文管理 contextlib ...

  2. python上下文管理器细读

    test 1 上下文管理器,将生成器转化为上下文管理器 import contextlib @contextlib.contextmanager def a(): print(1) yield pri ...

  3. python上下文管理器ContextLib及with语句

    http://blog.csdn.net/pipisorry/article/details/50444736 with语句 with语句是从 Python 2.5 开始引入的一种与异常处理相关的功能 ...

  4. python 上下文管理器contextlib.ContextManager

    1 模块简介 在数年前,Python 2.5 加入了一个非常特殊的关键字,就是with.with语句允许开发者创建上下文管理器.什么是上下文管理器?上下文管理器就是允许你可以自动地开始和结束一些事情. ...

  5. Python上下文管理器

    在Python中让自己创建的函数.类.对象支持with语句,就实现了上线文管理协议.我们经常使用with open(file, "a+") as f:这样的语句,无需手动调用f.c ...

  6. Python上下文管理器 with

    对于系统资源的操作,如:文件操作.数据库操作等,我们往往打开文件.连接数据库后忘了将其close掉,这时就可能会引发异常,因此我们常用的做法是: # coding:utf-8 f = open(&qu ...

  7. Python上下文管理器(Context managers)

    上下文管理器(Context managers) 上下文管理器允许你在有需要的时候,精确地分配和释放资源. 使用上下文管理器最广泛的案例就是with语句了.想象下你有两个需要结对执行的相关操作,然后还 ...

  8. 吃透Python上下文管理器

    什么是上下文管理器? 我们常见的with open操作文件,就是一个上下文管理器.如: with open(file, 'rb') as f: text = f.read() 那上下文管理器具体的定义 ...

  9. Python上下文管理器你学会了吗?

    ​什么是上下文管理器 对于像文件操作.连接数据库等资源管理的操作,我们必须在使用完之后进行释放,不然就容易造成资源泄露.为了解决这个问题,Python的解决方式便是上下文管理器.上下文管理器能够帮助你 ...

随机推荐

  1. java Socket实现简单在线聊天(一)

    最近的项目有一个在线网页交流的需求,由于很久以前做过的demo已经忘记的差不多了,因此便重新学习一下. 我计划的大致实现步骤分这样几大步: 1.使用awt组件和socket实现简单的单客户端向服务端持 ...

  2. hi3531的i2c部分

    一.关于编译Hi3531 SDK: 之前编译SDK时编译到make uImage总出错,一是找不到.config文件,这个问题是必须先make menuconfig 然后保存.config文件. 二是 ...

  3. (十六)java中的String

    String:字符串类型,是java中最常用的引用类型,String是不可变的,java.lang.String是由final修饰,此类不可被继承.     String是不可变的,指的是字符串一旦创 ...

  4. Python中ValueError: invalid literal for int() with base 10 的实用解决办法

    爬虫代理IP由芝麻HTTP服务供应商提供今天在写爬虫程序的时候由于要翻页,做除法分页的时候出现了 totalCount = ' totalPage = int(totalCount)/20 Value ...

  5. HashMap,LinkedHashMap,TreeMap对比

    共同点: HashMap,LinkedHashMap,TreeMap都属于Map:Map 主要用于存储键(key)值(value)对,根据键得到值,因此键不允许键重复,但允许值重复. 不同点: 1.H ...

  6. Duplicate entry '0' for key 'PRIMARY'的一种可能的解决办法

    在MySQL设计好数据库往往数据库中插入数据的时候, 因为主键ID默认是不赋值的,只给其他项目赋值了,相关的SQL代码是这样的 StringBuilder strSql = new StringBui ...

  7. webpack学习(一):webpack 介绍&安装&常用命令

    一.简单介绍 什么是Webpack Webpack是一款用户打包前端模块的工具,它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源. 主要是用来打包在浏览器端使用的ja ...

  8. C#异常处理--C#基础

    try...catch:捕获异常try...finally:清除异常try..catch...finily:处理所有异常 1.捕获异常 using System; using System.Colle ...

  9. MyEclipse 2014专业版的破解--Windows系统的软件安装

    一.破解前的准备 MyEclipse2014破解包: 您可以到计算机相关专业所用软件---百度云链接下载中找到链接地址进行下载. 二.破解步骤 1.打开破解文件资源包 2.执行run.bat 3.输入 ...

  10. 一个小的tab切换插件

    1//使用 var t1=new Tab({ etype:'onmou',//默认点击触发,如果事件写错了,当作单击 autoplay:2000,//有时间值(按照事件自动播放)和false(不自动播 ...