什么是Python“with”语句用于?

时间:2010-09-28 14:37:24

标签: python flask

我试图理解python中的with语句。在任何地方我都会看到它打开和关闭文件,并且意味着要替换try-finally块。有人也可以发布其他一些例子。我只是在尝试烧瓶,并且其中有丰富的陈述。绝对要求某人提供一些明确的信息。

3 个答案:

答案 0 :(得分:9)

有一个很好的解释here。基本上,with语句在关联对象上调用两个特殊方法。 __enter__和__exit__方法。 enter方法返回与“with”语句关联的变量。虽然在语句执行后调用__exit__方法来处理任何清理(例如关闭文件指针)。

答案 1 :(得分:9)

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:时,不需要进行此类检查 - 我可以立即看到锁定将被正确释放。

答案 2 :(得分:1)

PEP343中有12个使用with的示例,包括文件打开示例:

  1. 用于确保在开始时获取锁定的模板    块,在块被放置时被释放
  2. 用于打开确保文件已关闭的文件的模板    当剩下块时
  3. 用于提交或回滚数据库的模板    交易
  4. 示例1在没有生成器的情况下重写
  5. 暂时重定向stdout
  6. opens()上的一个变体,它也返回错误条件
  7. 另一个有用的例子是阻止的操作    信号
  8. 此功能的另一个用途是Decimal上下文
  9. 这是十进制模块的简单上下文管理器
  10. 通用的“对象关闭”上下文管理器
  11. release()上下文,通过交换acquire()和release()调用暂时释放以前获取的锁
  12. 自动嵌套的“嵌套”上下文管理器      从左到右提供的上下文,以避免过度      压痕