Catching an exception while using a Python 'with' statement Catching an exception while using a Python 'with' statement python python

Catching an exception while using a Python 'with' statement


from __future__ import with_statementtry:    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()


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.

@contextmanagerdef 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")


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