open() and EOFError
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Mon Jul 7 14:07:24 EDT 2014
On Mon, 07 Jul 2014 20:31:53 +0300, Marko Rauhamaa wrote:
> If the open() call is guarded against exceptions (as it usually should),
> one must revert to the classic syntax:
>
> try:
> f = open(path)
> except IOError:
> ...
> try:
> ...
> finally:
> f.close()
try:
f = open(path)
except Whatever:
handle_error()
else:
with f:
do_stuff()
While I agree with the general idea that try blocks should be as narrow
*as reasonable*, they shouldn't be as narrow *as possible* since one can
start guarding against unreasonable things.
try:
open
except NameError:
...
else:
try:
f = open(filename)
except ZeroDivisionError:
# Just in case open has been monkey-patched.
...
except NameError:
# Oops! Forgot to bind a value to filename!
# Or maybe another thread deleted open??? Woe, woe!!!
...
The thing is, even if you catch these bizarre things, what are you going
to do with them? If you can't do anything about it, there's no point
catching the exception -- never catch anything you can't recover from, or
otherwise handle. Just treat it as a fatal error and let it cause a
traceback.
As a general rule of thumb, if you have two things which (under
reasonable circumstances) might fail in *different* ways, then it's okay
to put them in the same try block, and then catch the two exceptions
separately:
try:
do_this(with_that())
except ThatError:
...
except ThisError:
...
If you handle the exceptions the same way, then you can still put them in
the same try block:
try:
do_this(with_that())
except (ThatError, ThisError):
...
The worst case is when they might fail with the same exception, but you
need to handle the failures differently:
try:
a = with_that()
except ThatError:
...
else:
try:
do_this(a)
except ThatError:
...
That gets old really quickly! But then, handling errors is always the
ugliest part of coding. Hiding the messy details inside a function is
often a good idea.
--
Steven
More information about the Python-list
mailing list