Catching an exception while using a Python 'with' statement
from __future__ import with_statement
try:
with open( "a.txt" ) as f :
print f.readlines()
except EnvironmentError: # parent of IOError, OSError *and* WindowsError where available
print 'oops'
If you want different handling for errors from the open call vs the working code you could do:
try:
f = open('foo.txt')
except IOError:
print('error')
else:
with f:
print f.readlines()
Catching an exception while using a Python 'with' statement
The with statement has been available without the __future__
import since Python 2.6. You can get it as early as Python 2.5 (but at this point it's time to upgrade!) with:
from __future__ import with_statement
Here's the closest thing to correct that you have. You're almost there, but with
doesn't have an except
clause:
with open("a.txt") as f: print(f.readlines()) except: # <- with doesn't have an except clause. print('oops')
A context manager's __exit__
method, if it returns False
will reraise the error when it finishes. If it returns True
, it will suppress it. The open
builtin's __exit__
doesn't return True
, so you just need to nest it in a try, except block:
try:
with open("a.txt") as f:
print(f.readlines())
except Exception as error:
print('oops')
And standard boilerplate: don't use a bare except:
which catches BaseException
and every other possible exception and warning. Be at least as specific as Exception
, and for this error, perhaps catch IOError
. Only catch errors you're prepared to handle.
So in this case, you'd do:
>>> try:
... with open("a.txt") as f:
... print(f.readlines())
... except IOError as error:
... print('oops')
...
oops
The best "Pythonic" way to do this, exploiting the with
statement, is listed as Example #6 in PEP 343, which gives the background of the statement.
@contextmanager
def opened_w_error(filename, mode="r"):
try:
f = open(filename, mode)
except IOError, err:
yield None, err
else:
try:
yield f, None
finally:
f.close()
Used as follows:
with opened_w_error("/etc/passwd", "a") as (f, err):
if err:
print "IOError:", err
else:
f.write("guido::0:0::/:/bin/sh\n")