上下文管理器

  一直对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. Windows & Linux服务器如何禁用ping总结

      有时候你ping一些服务器或网站,你会发现ping不通,这个是因为对方出于安全因素(security reason)或避免网络拥堵(avoid network congestion)等原因,禁用了 ...

  2. 经典案例之MouseJack

    引言:在昨天的文章<无线键鼠监听与劫持>中,我们提到今天会向您介绍一个无线键鼠的监听与劫持的经典案例,<MouseJack>:MouseJack能利用无线鼠标和键盘存在的一些问 ...

  3. VxWorks 任务

    任务:在执行时每个程序都被称之为任务.VxWorks操作系统中,任务可以直接地或者以共享方式访问大多数系统资源,为了维护各自的线程,每个任务必须保持有足够的上下文环境.(1)    任务状态:就绪(R ...

  4. 6.1 MSI/MSI-X Capability结构

    PCIe设备可以使用MSI或者MSI-X报文向处理器提交中断请求,但是对于某个具体的PCIe设备,可能仅支持一种报文.在PCIe设备中含有两个Capability结构,一个是MSI Capabilit ...

  5. 硬盘分区表格式GUID和MBR知识普及

    我们的电脑硬盘分区格式一共有两种,一种是GUID(GPT),一种是MBR 如果你的电脑原装系统是win8或者以上的,那么他的硬盘分区表格式为GUID(GPT)格式的:如果是win7以下的,那么一般就是 ...

  6. dojo API中英文缩写的意思

    dojo API中英文缩写的意思 1.A-Array(数组) 2.B-Boolean(布尔类型) 3.C-Constructor(构造器) 4.D-Date(日期) 5.{}-DomNode(节点) ...

  7. 不使用spring的情况下用java原生代码操作mongodb数据库的两种方式

    由于更改了mongodb3.0数据库的密码,导致这几天storm组对数据进行处理的时候,一直在报mongodb数据库连接不上的异常.   主要原因实际上是和mongodb本身无关的,因为他们改的是配置 ...

  8. AXI总线简介

    AXI全称Advanced eXtensible Interface,是Xilinx从6系列的FPGA开始引入的一个接口协议,主要描述了主设备和从设备之间的数据传输方式.在ZYNQ中继续使用,版本是A ...

  9. HighCharts之气泡图报错

    HighCharts之气泡图报错 具体报错如下: uncaught exception: Highcharts error #17: www.highcharts.com/errors/17     ...

  10. app_offline.htm的作用

    如果你要COPY站点,进行站点维护,部署,和进行大量修改,有可能要停掉你的WEB应用程序了,而以一个友好的方式提示给用户,比如什么"本网站正在更新"等等的信息可以建立一个叫app_ ...