你如何在 Python 中测试 file.read() 错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/374768/
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-11-03 19:59:07  来源:igfitidea点击:

How do you test a file.read() error in Python?

pythonfile-ioerror-handling

提问by Bill the Lizard

I have the following code (adapted from an example given in Dive Into Python) that reads the entire contents of a file into a buffer.

我有以下代码(改编自Dive Into Python 中给出的示例)将文件的全部内容读入缓冲区。

buffer = ""

try:
    file = open(postFileName, 'rU')
    try:
        # Read the entire POST log file into a buffer
        buffer += file.read()
    finally:
        file.close()
except IOError:
    buffer += "The POST file could not be opened."

What's bothering me about this code is the inner try/finally block without an except block. Do I need an except block in there? Can the call to read()fail after the call to open()was successful? I know the try-except-finally is now unified, so adding one, at least syntactically, is not a problem.

这段代码困扰我的是内部 try/finally 块,而没有一个 except 块。我在那里需要一个except块吗?调用成功read()后能否调用失败open()?我知道 try-except-finally 现在统一了,所以添加一个,至少在语法上,不是问题。

If I add an except block, under what conditions will it be executed, and how do I write a test to make sure it runs under those conditions?

如果我添加一个 except 块,它将在什么条件下执行,以及如何编写测试以确保它在这些条件下运行?

Additionally, if I don'tneed an except block, then why do I need the inner try/finally block at all?

此外,如果我没有需要一个除块,那么为什么需要内部try / finally块呢?

回答by S.Lott

I find that finally blocks are often overused. The file close (and a few other similar patterns) are so important that Python 3.0 will have a withstatement just to cover this base in a slightly less obscure way.

我发现 finally 块经常被过度使用。文件关闭(和其他一些类似的模式)非常重要,以至于 Python 3.0 将有一个with语句,只是为了以稍微不那么晦涩的方式覆盖这个基础。

  • Do I need an except with a finally?

    That hits on the confusing nature of this specific example, and why they added the withstatement.

    The finallydoes "no matter what" cleanup. Exception or no exception, the finallyis always executed.

  • Can the call to read() fail after the call to open() was successful?

    All OS calls, all I/O calls (almost everything) can raise an exception. All kinds of bad things can happen after open and before read.

  • If I add an exceptblock, under what conditions will it be executed?

    Read up on files. There are lots of goofy I/O errors that can occur between open and read. Also, read up on the built-in exceptions. https://docs.python.org/2/library/exceptions.html

  • How do I write a test to make sure it runs under those conditions?

    You'll need a mock file object. This object will responds to openbut raises an IOErroror OSErroron every read.

  • If I don't need an except block, then why do I need the inner try/finally block at all?

    Cleanup. The finallywill be executed no matter what exception is raised.

  • 我需要一个除了最后吗?

    这触及了这个特定示例的令人困惑的本质,以及他们添加with语句的原因。

    最后也“不管是什么”的清理工作。不管有无异常,finally总是被执行。

  • 调用 open() 成功后调用 read() 是否会失败?

    所有 OS 调用、所有 I/O 调用(几乎所有)都可能引发异常。打开之后,阅读之前,各种不好的事情都可能发生。

  • 如果我添加一个except块,它会在什么条件下被执行?

    阅读文件。在打开和读取之间可能会发生许多愚蠢的 I/O 错误。另外,请阅读内置异常。 https://docs.python.org/2/library/exceptions.html

  • 我如何编写测试以确保它在这些条件下运行?

    您将需要一个模拟文件对象。这个对象将响应open而引发IOErrorOSError每个read

  • 如果我不需要一个 except 块,那为什么我需要内部 try/finally 块呢?

    清理。无论引发什么异常,finally都会被执行。

Try this. See what it does.

试试这个。看看它有什么作用。

try:
 raise OSError("hi mom")
finally:
 print "Hmmm"

回答by Brian

I disagree with the other answers mentioning unifying the try / except / finally blocks. That would change the behaviour, as you wouldn't want the finally block to try to close the file if the open failed. The split blocks are correct here (though it may be better using the new "with open(filename,'rU') as f" syntax instead).

我不同意其他提到统一 try / except / finally 块的答案。这将改变行为,因为如果打开失败,您不希望 finally 块尝试关闭文件。拆分块在这里是正确的(尽管使用新的 " with open(filename,'rU') as f" 语法可能会更好)。

There are reasons the read() could fail. For instance the data could be too big to fit into memory, or the user may have signalled an interrupt with control-C. Those cases won't be caught by the IOError, but are left to be handled (or not) by the caller who may want to do different things depending on the nature of the application. However, the code does still have an obligation to clean up the file, even where it doesn't deal with the error, hence the finally without the except.

read() 可能失败是有原因的。例如,数据可能太大而无法放入内存,或者用户可能已经用 control-C 发出中断信号。这些情况不会被 IOError 捕获,而是由调用者处理(或不处理),他们可能想要根据应用程序的性质做不同的事情。但是,代码仍然有义务清理文件,即使它不处理错误,因此 finally 没有except。

回答by Oli

With a recent version of Python, you don't need to nest try-except and try-finally. try-except-finally has been unified:

使用最新版本的 Python,您不需要嵌套 try-except 和 try-finally。try-except-finally 已经统一:

try:
  non_existing_var
except:
  print 'error'
finally:
  print 'finished'