Python 中的 with 语法经常被用来在管理资源的访问和清理中,常见的场景有文件的使用和关闭,锁的获取和释放等等。

with open("file.txt") as file:
	data = file.read()

with 语法特别容易联想起 Java 中的 try-with-resources AutoCloseable,同样实现资源的自动释放。

基本格式

从基本使用开始了解 with,with 的结构如下:

with context_expression [as target(s)]:
    content

With 工作原理

如果要聊 with 的实现,就不得不提到 Python 中的上下文管理:

with 语句执行过程:

  • 执行 context_expression 生成上下文管理器 context_manager
  • 调用 context manager 的 enter() 方法,如果使用 as 子句,将 enter 方法返回值赋值给 target(s)
  • 执行 with-body
  • 不管是否异常,执行 exit() 方法,exit() 方法负责清理工作
  • 出现异常时, exit(type, value, traceback) 返回 False,重新抛出异常,让 with 之外的语句逻辑来处理异常;如果返回 True,这忽略异常,不再对异常处理

    class Dummy: def enter(self): print “in enter” return “Foo” def exit(self, exc_type, exc_val, exc_tb): print “in exit

    def get_dummy(): return Dummy()

    with get_dummy() as dummy: print “Dummy: “, dummy

除了上面这种实现 __enter____exit__ 方法来生成 context manger 的方式,还可以使用 contextlib

from contextlib import contextmanager

@contextmanager
def open_file(name, mode):
  f = open(name, mode)
  yield f
  f.close()

然后使用:

with open_file('file.txt', 'w') as f:
  f.write("Hello, world.")

reference