我有以下代码(改编自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."
这个代码困扰我的是没有except块的内部try / finally块。我需要一个除了块吗?呼叫read()
成功后,open()
的呼叫是否会失败?我知道try-except-finally现在是统一的,所以添加一个,至少在语法上,不是问题。
如果我添加一个except块,它将在什么条件下执行,以及如何编写测试以确保它在这些条件下运行?
另外,如果我不需要一个except块,那为什么我需要内部try / finally块呢?
答案 0 :(得分:7)
我发现最后的块经常被过度使用。文件关闭(以及一些其他类似的模式)非常重要,以至于Python 3.0将使用 with 语句来覆盖这个基础,而不是那么模糊。
我最后需要一个除外吗?
这会影响这个特定示例的混乱性质,以及为什么他们添加 with 语句。
终于做“无论什么”清理。 最终总是被执行。
在调用open()成功后,对read()的调用是否会失败?
所有OS调用,所有I / O调用(几乎所有内容)都可能引发异常。打开之后和阅读之前都会发生各种不好的事情。
如果我添加除块,它将在什么条件下执行?
阅读文件。打开和读取之间可能会发生许多愚蠢的I / O错误。另外,请阅读内置异常。 https://docs.python.org/2/library/exceptions.html
如何编写测试以确保它在这些条件下运行?
你需要一个模拟文件对象。此对象将响应open
,但会在IOError
OSError
上提出read
或try:
raise OSError("hi mom")
finally:
print "Hmmm"
。
如果我不需要一个except块,那为什么我需要内部的try / finally块呢?
清理。无论引发什么异常,都会执行 finally 。
试试这个。看看它做了什么。
{{1}}
答案 1 :(得分:3)
我不同意提及统一try / except / finally块的其他答案。这会改变行为,因为如果打开失败,你不希望finally块尝试关闭文件。这里的拆分块是正确的(尽管使用新的“with open(filename,'rU') as f
”语法可能会更好)。
read()可能会失败。例如,数据可能太大而无法放入内存中,或者用户可能已通过control-C发出中断信号。 IOError不会捕获这些情况,但是可能需要根据应用程序的性质执行不同操作的调用者处理(或不处理)这些情况。 但是,代码仍然有义务清理文件,即使它没有处理错误,因此最终没有除外。
答案 2 :(得分:0)
使用最新版本的Python,您不需要嵌套try-except和try-finally。 try-except-finally已统一:
try:
non_existing_var
except:
print 'error'
finally:
print 'finished'
答案 3 :(得分:0)
谷歌搜索了一下Unified try/except/finally
希望它有所帮助;)