什么是Python"with"语句用于?

Ras*_*mus 4 python flask

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

GWW*_*GWW 9

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

  • 我和OP在一起.您给出的链接演示了Alice描述的"打开和关闭文件"示例,但它实际上并没有显示*为什么*它比"data = open("x.txt")更好.read()".似乎"有"是我应该考虑的事情,但是如果我能说出它实际上有什么好处的话就会变得愚蠢. (2认同)

nco*_*lan 9

with声明的想法是使"做正确的事"成为阻力最小的道路.虽然文件示例是最简单的,但线程锁实际上提供了一个非常明显的错误代码的更典型示例:

try:
    lock.acquire()
    # do stuff
finally:
    lock.release()
Run Code Online (Sandbox Code Playgroud)

此代码被破坏 - 如果锁定获取失败,将抛出错误的异常(因为代码将尝试释放它从未获取的锁定),或者更糟糕的是,如果这是一个递归锁定,它将被释放早.正确的代码如下所示:

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

通过使用with语句,不可能出错,因为它内置于上下文管理器中:

with lock: # The lock *knows* how to correctly handle acquisition and release
  # do stuff
Run Code Online (Sandbox Code Playgroud)

with声明帮助的另一个地方类似于函数和类装饰器的主要好处:它采用"两片"代码,可以用任意数量的代码行分隔(装饰器的函数定义,try块在当前的情况)并将其转换为"单片"代码,程序员只是简单地声明他们正在尝试做什么.

对于简短的例子,这看起来并不是一个很大的收获,但它在查看代码时实际上会产生巨大的差异.当我lock.acquire()在一段代码中看到时,我需要向下滚动并检查相应的代码lock.release().with lock:但是,当我看到,不需要这样的检查 - 我可以立即看到锁将被正确释放.