在线文档教程

contextlib

contextlib - 具有语句上下文的实用程序

2.5版本中的新功能。

源代码: Lib / contextlib.py

该模块为涉及该with语句的常见任务提供实用程序。有关更多信息,请参阅上下文管理器类型和使用语句上下文管理器。

提供的功能:

contextlib.contextmanager(func)

该函数是一个装饰器,可用于为语句上下文管理器定义工厂函数,而无需创建类或单独的__enter __()和__exit __()方法。

一个简单的例子(这不建议作为生成HTML的真正方法!):

from contextlib import contextmanager @contextmanager def tag(name): print "<%s>" % name yield print "</%s>" % name >>> with tag("h1"): ... print "foo" ... <h1> foo </h1>

被调用的函数在调用时必须返回一个生成器引发器。此迭代器必须产生恰好一个值,该值将绑定到with语句as子句中的目标(如果有的话)。

在发生器产生的点上,嵌套在with语句中的块被执行。该模块退出后,发电机恢复运行。如果块中发生未处理的异常,则在发生产量的位置将其重新发送到生成器中。因此,你可以使用一个try... except... finally语句来捕获错误(如果有的话),或确保一些清理发生。如果一个异常仅仅为了记录它或者执行一些操作而被捕获(而不是完全压制它),那么生成器必须重新评估该异常。否则,生成器上下文管理器将向with语句指示该异常已被处理,并且执行将随着语句紧随该with语句而继续。

contextlib.nested(mgr1[, mgr2[, ...]])

将多个上下文管理器组合成一个嵌套的上下文管理器。

此功能已被弃用,以支持该with报表的多个管理形式。

这个函数比with声明的多个管理器形式的优点是,解析参数允许它与可变数目的上下文管理器一起使用,如下所示:

from contextlib import nested with nested(*managers): do_something()

请注意,如果__exit__()其中一个嵌套上下文管理器的方法指示应该抑制异常,则不会将任何异常信息传递给任何其余的外部上下文管理器。同样,如果__exit__()其中一个嵌套管理器的方法引发异常,则以前的任何异常状态都将丢失; 新的异常将传递给__exit__()任何剩余的外部上下文管理器的方法。一般而言,__exit__()方法应该避免引发异常,尤其是不应该重新提出通过的异常。

这个函数有两个主要的奇怪特点,导致它被弃用。首先,作为上下文管理器都被构造在调用函数前,__new__()__init__()内上下文管理器的方法并不实际上由外上下文管理器的范围所覆盖。这意味着,例如,使用nested()打开两个文件是一个编程错误,因为如果在打开第二个文件时引发异常,第一个文件不会立即关闭。

其次,如果__enter__()内部上下文管理器之一的方法引发了被__exit__()外部上下文管理器之一的方法捕获和压制的异常,则此构造将引发RuntimeError而不是跳过with语句的主体。

需要支持嵌套可变数量的上下文管理器的开发人员可以使用该warnings模块来抑制由此函数引发的DeprecationWarning,或者将此函数用作特定于应用程序的实现的模型。

自2.7版弃用:with-statement现在直接支持此功能(没有令人困惑的错误倾向)。

contextlib.closing(thing)

返回一个上下文管理器,在完成该块后关闭事物。这基本相当于:

from contextlib import contextmanager @contextmanager def closing(thing): try: yield thing finally: thing.close()

并让你编写这样的代码:

from contextlib import closing import urllib with closing(urllib.urlopen('http://www.python.org')) as page: for line in page: print line

而不需要明确关闭page。即使发生错误,page.close()with块被退出时也会被调用。

扩展内容

PEP 343 - “with”语句Pythonwith语句的规范,背景和示例。