python中上下文管理器的用途是什么

use*_*629 6 python

我正在阅读http://eigenhombre.com/2013/04/20/introduction-to-context-managers/.

在里面:

上下文管理器是一种在您需要的地方分配和释放某种资源的方法.最简单的例子是文件访问:

with file("/tmp/foo", "w") as foo:
    print >> foo, "Hello!"
Run Code Online (Sandbox Code Playgroud)

这基本上相当于:

foo = file("/tmp/foo", "w")
try:
    print >> foo, "Hello!"
finally:
    foo.close()
Run Code Online (Sandbox Code Playgroud)

文章接着进行了更多的解释,但我仍然不确定我是否理解他们的目的.有人可以澄清一下.还有什么是"背景"?

我已经看过试图用语句和上下文管理器来理解python,但我又不确定上下文管理器的用途是什么?它只是"尝试......终于......"的替代语法,还是它们的其他目的

Bha*_*rel 11

什么是上下文管理器?

上下文管理器可以帮助提供资源(尽管可能会用得更多).该背景是基本的资源.

假设你打开了一个写文件:

f = open(path, "w")
Run Code Online (Sandbox Code Playgroud)

您现在有一个打开的文件句柄.在处理文件期间,没有其他程序可以写入它.为了让其他程序写入它,您必须关闭文件句柄:

f.close()
Run Code Online (Sandbox Code Playgroud)

但是,在关闭文件之前发生错误:

f = open(path, "w")
data = 3/0  # Tried dividing by zero. Raised ZeroDivisionError
f.write(data)
f.close()
Run Code Online (Sandbox Code Playgroud)

现在会发生的是,函数或整个程序将退出,同时保留文件的打开句柄.(CPython在终止时清除句柄,句柄与程序一起释放,但你不应该依赖它)

一个with语句确保一旦你留下它的缩进,它将关闭文件句柄:

with open(path, "w") as f:
    data = 3/0  # Tried dividing by zero. Raised ZeroDivisionError
    f.write(data)
# Here, the file is already closed automatically, no matter what happened.
Run Code Online (Sandbox Code Playgroud)

with语句可用于更多的事情.例如:threading.Lock()

lock = threading.Lock()
with lock:  # Lock is acquired
   do stuff...
# Lock is automatically released.
Run Code Online (Sandbox Code Playgroud)

几乎所有使用上下文管理器完成的操作都可以完成,try: ... finally: ...但上下文管理器使用起来更好,更舒适,更易读,并且通过实现__enter____exit__提供易于使用的界面.


如何实施上下文管理器?

什么是__enter____exit__

创建上下文管理器是通过实现__enter__()__exit__()在普通类中完成的.

__enter__()告诉上下文管理器启动时和__exit__()上下文管理器存在时要做什么(__exit__()如果发生异常,则给出方法的异常)

可以在contextlib中找到创建上下文管理器的快捷方式.它将生成器包装为上下文管理器,如下所示:

from contextlib import contextmanager

@contextmanager
def tag(name):
    print("<%s>" % name)
    yield
    print("</%s>" % name)

>>> with tag("h1"):
...    print("foo")
...
<h1>
foo
</h1>
Run Code Online (Sandbox Code Playgroud)

从Python文档中获取的示例.