109

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

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

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

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

这里“with”语句的主要好处是我们可以摆脱三行代码吗?这个用例对我来说似乎没有什么吸引力(尽管我知道“with”语句还有其他用途)。

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

EDIT2:前几个答案一般谈论使用“with”的好处,但这些似乎是边际收益。多年来,我们都(或应该)明确地调用 f.close()。我想一个好处是马虎的编码员将受益于使用“with”。

4

4 回答 4

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

等效的旧式代码将是:

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

如您所见,该with语句可以减少出错的可能性。在较新版本的 Python(2.7、3.1)中,您还可以在一条with语句中组合多个表达式。例如:

with open("input", "r") as inp, open("output", "w") as out:
    out.write(inp.read())

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

于 2010-09-05T01:20:19.177 回答
7

如果finally块的内容是由正在打开的文件对象的属性决定的,为什么文件对象的实现者不应该是写入finally块的人呢?这就是语句的好处with,远远超过在这个特定实例中为您节省三行代码。

是的,您组合的方式with几乎try-except是唯一的方法,因为open语句本身引起的异常错误无法在with块中捕获。

于 2010-09-04T11:53:55.570 回答
1

我认为您对“with”语句的理解是错误的,它只会减少行数。它实际上进行初始化并处理拆卸。

在您的情况下,“与”确实

  • 打开一个文件,
  • 处理其内容,以及
  • 确保关闭它。

这是理解“with”语句的链接: http: //effbot.org/zone/python-with-statement.htm

编辑:是的,您对“with”的使用是正确的,并且两个代码块的功能是相同的。关于为什么使用“with”的问题?这是因为您从中获得的好处。就像您提到的意外丢失 f.close() 一样。

于 2010-09-04T11:55:02.623 回答
-6

以下代码更 Pythonic 的方式是:

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

try:
    f = open("file", "r")
except IOError:
    <whatever>
else:
    f.close()
于 2015-10-13T21:21:10.820 回答