[Tutor] question regarding python exception handling

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Sun Jan 30 10:14:52 CET 2005



On Sat, 29 Jan 2005, Roy wrote:

> I am learning about python exception handling. I am reading "Python in a
> Nutshell". In the chapter of exception handling, it says: Note that the
> try/finally form is distinct from the try/except form: a try statement
> cannot have both except and finally clauses, as execution order might be
> ambiguous.

Hi Roy,

Caveat: what I write below might not actually be right!  Acording to amk:

   http://www.amk.ca/python/writing/warts.html

under the header "Catching Multiple Exceptions", the reason we can't do it
is just pure laziness from Python's implementors.  So I might be inventing
a line of reasoning that isn't the language designer's original intention.
*grin*



Let's take a look at a bit of Java code, and then compare that to Python.

/*** Java example ***/
PreparedStatement stmt = conn.prepareStatement
    ("select name from pub_article");
try {
    ResultSet rs = stmt.executeQuery();
    while (rs.next()) {
        System.out.println(rs.getString(1));
    }
} catch(SQLException e) {
    e.printStackTrace();
} finally {
    stmt.close()
}
/*****/


Here is a rough translation of that code in Python:

### Python example ###
cursor = conn.cursor()
try:
    try:
        cursor.execute("select name from pub_article")
        for (name,) in cursor.fetchall():
            print name
    except DatabaseError:
        traceback.print_exc()
finally:
    cursor.close()
######



> I don't understand the reason why except and finally clauses cannot be
> together. I know they can be together in java. how does it cause
> ambiguous execution order? An example may help me understand.


The block structure in the Java pseudocode:

/******/
try {
    // just some code
} catch(...) {
    // exception-handling block
} finally {
    // finally block
}
/******/

implies a flow-of-control that is a bit deceptive.  In Java, the visual
block structure implies that 'catch' and 'finally' behave like peers, like
the "if/else if" or "switch/case" flow-of-control statements.

We know that when an exception happens, the flow of control does this
thing where it goes into "exception-handling block", and then weaves
around into the "finally block".  But we also hit the finally block even
if no exception occurs.

And that's where a possible confusion can happen: the 'finally' block
visually looks like a peer to the other 'catch' blocks, but it serves an
entirely different kind of behavior.  Conceptually, the 'finally' block
"wraps"  around the behavior of the 'catch': it fires off regardless if we
hit a catch block or not.

Python's syntax makes that the flow of control visible through its block
nesting:

###
try:
    try:
        ...
    except ...:
       ...
finally:
    ...
###


Here, the block structure makes it clear that the inner try/except stuff
is in the context of a try/finally block.  This is one case where Python
is more verbose than Java.


I hope this sounds reasonable.  *grin*  Best of wishes to you!



More information about the Tutor mailing list