我试图理解 python 中的 with 语句。我到处都看到它谈论打开和关闭文件,并且旨在替换 try-finally 块。有人也可以发布一些其他例子吗?我只是在尝试 Flask,里面有大量的 with 语句。绝对要求有人提供一些澄清。

有帮助吗?

解决方案

有一个非常好的解释这里。基本上,with语句调用相关对象的两个特殊的方法。该__enter__和__exit__方法。该输入方法返回与“用”的语句关联的变量。虽然__exit__方法执行语句之后调用来处理任何清理(如关闭文件指针)。

其他提示

with语句的想法是要“做正确的事”阻力最小的路径。而文件实例是最简单的,穿线锁实际提供的非明显缺陷代码的更典型的例子:

try:
    lock.acquire()
    # do stuff
finally:
    lock.release()

此代码被打破 - 如果锁定获取以往任何时候都失败了,要么有错误,会引发异常(因为代码将尝试释放它从未获得锁),或者更糟的是,如果这是一个递归锁,它将被提前释放。正确的代码看起来是这样的:

lock.acquire()
try:
    # do stuff
finally:
    # If lock.acquire() fails, this *doesn't* run
    lock.release()

通过使用with声明,就不可能得到这个错误的,因为它是建立在上下文管理器:

with lock: # The lock *knows* how to correctly handle acquisition and release
  # do stuff

在其他地方,with语句有助于大大类似于的功能和类装饰器的主要好处:它以“两件式”的代码,其可以由行代码的任意数量的分离(装饰函数定义在目前的情况下,try块)并将其转化为“一体”的代码,其中程序员只需前面声明了什么,他们正在尝试做。

对于短的例子,这看起来并不像一个大的提升,但审查代码时,它实际上使一个巨大的差异。当我在一块的代码中看到lock.acquire(),我需要向下滚动,并检查相应的lock.release()。当我看到with lock:,虽然,不需要这样的检验 - 我可以立即看到,锁将被正确释放

有十二个使用示例 withPEP343, ,包括文件打开示例:

  1. 一个用于确保在块开始时在块开始时获得的锁的模板
  2. 一个用于打开文件的模板,该文件可确保在剩余块时关闭文件
  3. 用于提交或回滚数据库事务的模板
  4. 示例 1 不使用生成器重写
  5. 暂时重定向标准输出
  6. opens() 的变体也返回错误条件
  7. 另一个有用的例子是一个封锁信号的操作
  8. 此功能的另一个用途是十进制上下文
  9. 这是十进制模块的简单上下文管理器
  10. 通用的“对象关闭”上下文管理器
  11. 一个release()上下文,通过交换acquire()和release()调用来临时释放先前获取的锁
  12. 从左到右的“嵌套”上下文管理器自动筑巢的上下文以避免过多的凹痕
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top