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.
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.
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?
Additionally, if I don't need an except block, then why do I need the inner try/finally block at all?
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 with statement just to cover this base in a slightly less obscure way.
Do I need an except with a finally?
That hits on the confusing nature of this specific example, and why they added the with statement.
The finally does "no matter what" cleanup. Exception or no exception, the finally is 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 except block, 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 open
but raises an IOError
or OSError
on every read
.
If I don't need an except block, then why do I need the inner try/finally block at all?
Cleanup. The finally will be executed no matter what exception is raised.
Try this. See what it does.
try:
raise OSError("hi mom")
finally:
print "Hmmm"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With