将 python "with" 语句与 try-except 块一起使用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3642080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:03:01  来源:igfitidea点击:

Using python "with" statement with try-except block

pythonfinallywith-statementtry-catchexcept

提问by gaefan

Is this the right way to use the python "with" statement in combination with a try-except block?:

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

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

If it is, then considering the old way of doing things:

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

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

Is the primary benefit of the "with" statement here that we can get rid of three lines of code? It doesn't seem that compelling to me for this use case(though I understand that the "with" statement has other uses).

这里“with”语句的主要好处是我们可以去掉三行代码吗?对于这个用例,对我来说似乎并不那么引人注目(尽管我知道“with”语句还有其他用途)。

EDIT: Is the functionality of the above two blocks of code identical?

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

EDIT2: The first few answers talk generally about the benefits of using "with", but those seem of marginal benefit here. We've all been (or should have been) explicitly calling f.close() for years. I suppose one benefit is that sloppy coders will benefit from using "with".

EDIT2:前几个答案一般谈论使用“with”的好处,但这些似乎是边际效益。多年来,我们一直(或应该)明确调用 f.close()。我想一个好处是草率的编码员会从使用“with”中受益。

采纳答案by Bernd Petersohn

  1. The two code blocks you gave are notequivalent
  2. The code you described as old way of doing thingshas a serious bug: in case opening the file fails you will get a second exception in the finallyclause because fis not bound.
  1. 你给出的两个代码块 等价
  2. 您描述为旧的做事方式的代码有一个严重的错误:如果打开文件失败,您将在finally子句中遇到第二个异常, 因为f没有绑定。

The equivalent old style code would be:

等效的旧样式代码是:

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

As you can see, the withstatement can make things less error prone. In newer versions of Python (2.7, 3.1), you can also combine multiple expressions in one withstatement. For example:

如您所见,该with语句可以使事情不易出错。在较新版本的 Python(2.7、3.1)中,您还可以在一个with语句中组合多个表达式。例如:

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

Besides that, I personally regard it as bad habit to catch any exception as early as possible. This is not the purpose of exceptions. If the IO function that can fail is part of a more complicated operation, in most cases the IOError should abort the whole operation and so be handled at an outer level. Using withstatements, you can get rid of all these try...finallystatements at inner levels.

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

回答by Peter Milley

If the contents of the finallyblock are determined by the properties of the file object being opened, why shouldn't the implementer of the file object be the one to write the finallyblock? That'sthe benefit of the withstatement, much more than saving you three lines of code in this particular instance.

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

And yes, the way you've combined withand try-exceptis pretty much the only way to do it, as exceptional errors caused within the openstatement itself can't be caught within the withblock.

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

回答by YoK

I think you got it wrong about "with" statement that it only reduces lines. It actually does initialization and handle teardown.

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

In your case "with" does

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

  • open a file,
  • process its contents, and
  • make sure to close it.
  • 打开一个文件,
  • 处理其内容,以及
  • 确保关闭它。

Here is link for understanding "with" statement : http://effbot.org/zone/python-with-statement.htm

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

Edit: Yes your usage of "with" is correct and functionality of both blocks of code is identical. Question about why to use "with" ? it's because of benefits you get with it. like you mentioned about accidentally missing f.close().

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

回答by Leo Liu

The more Pythonic way for the following codes is:

以下代码的更 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()