使用带有try-except块的python"with"语句

gae*_*fan 90 python finally try-catch with-statement except

这是将python"with"语句与try-except块结合使用的正确方法吗?:

try:
    with open("file", "r") as f:
        line = f.readline()
except IOError:
    <whatever>
Run Code Online (Sandbox Code Playgroud)

如果是,那么考虑旧的做事方式:

try:
    f = open("file", "r")
    line = f.readline()
except IOError:
    <whatever>
finally:
    f.close()
Run Code Online (Sandbox Code Playgroud)

这里"with"语句的主要好处是我们可以摆脱三行代码吗?对于这个用例来说,这似乎并不令我感到高兴(尽管我理解"with"语句还有其他用途).

编辑:上面两个代码块的功能是否相同?

EDIT2:前几个答案一般性地讨论了使用"with"的好处,但这些似乎在边缘效益.我们已经(或应该已经)多年来明确地调用f.close().我想一个好处是,草率编码器将从使用"with"中受益.

Ber*_*ohn 129

  1. 您提供的两个代码块 并不等效
  2. 您描述为旧的处理方式的代码存在严重错误:如果打开文件失败,您将在finally子句中获得第二个异常, 因为f它没有绑定.

等效的旧样式代码是:

try:
    f = open("file", "r")
    try:
        line = f.readline()
    finally:
        f.close()
except IOError:
    <whatever>
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,该with语句可以减少错误.在较新版本的Python(2.7,3.1)中,您还可以在一个with语句中组合多个表达式.例如:

with open("input", "r") as inp, open("output", "w") as out:
    out.write(inp.read())
Run Code Online (Sandbox Code Playgroud)

除此之外,我个人认为尽早发现任何例外都是不好的习惯.这不是例外的目的.如果可能失败的IO函数是更复杂操作的一部分,则在大多数情况下IOError应该中止整个操作,因此在外层处理.使用with语句,您可以try...finally在内部级别删除所有这些语句.

  • 尽早使用异常是很好的。Python 在许多情况下鼓励使用它们进行控制。 (3认同)

Pet*_*ley 6

如果finally块的内容是由打开的文件对象的属性确定的,为什么文件对象的实现者不应该是写finally块的实现者?这是with声明的好处,远不止在这个特定实例中保存三行代码.

是的,你结合的方式with,并try-except为几乎做到这一点的唯一方法,因为内造成特殊错误open本身不能内被捕获的语句with块.