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
语句的规范,背景和示例。