When to use exceptions (was Re: reducing if statements...)

Skip Montanaro skip at pobox.com
Tue Aug 21 19:53:18 EDT 2001


    Don> So, are there some good patterns, idioms, or whatever to provide
    Don> guidance on when to use exceptions vs. checking error codes,
    Don> etc. (other than the obvious general qualities: ease of use,
    Don> readability, modifiability, ...)?

I don't know that there are any codified examples of useful patterns for
using exceptions vs. checking error codes.  (Alex might know.  If anyone
would, I expect it would be him... ;-) Many modules define their own "error"
or "Error" exceptions that other modules will catch.  Most often they are
used in an error context.  Perhaps the one thing I've never seen done is to
use an exception across module boundaries to signal a non-error condition.
Also, note that you can have your cake and eat it too, because you can (and
many modules do) raise an exception and annotate it with messages or error
codes:

    try:
        somemodule.func(p1, p2, p3)
    except somemodule.Error, (code, msg):
        if code == 200:
            # an expected condition, warn and move on
            print msg
        else:
            # something we can't recover from - reraise the exception
            raise

The example I always think of when considering using exceptions vs. error
codes or flags in a non-error context is breaking out of a nested loop.
Since Python doesn't have a goto statement or multi-level break, people
often use flag variables to accomplish this:

    done = 0
    for i in range(len(mylist)):
        for j in range(len(mylist[i])):
            if some_predicate(mylist[i][j]):
                done = 1
                break
        if done:
            break
    if done:
        do_stuff_with(mylist[i][j])
    else:
        print "didn't find anything interesting..."

This always seemed pretty clumsy to me.  I prefer to use exceptions:

    class done(Exception): pass
    try:
        for i in range(len(mylist)):
            for j in range(len(mylist[i])):
                if some_predicate(mylist[i][j]):
                    raise done
    except done:
        do_stuff_with(mylist[i][j])
    else:
        print "didn't find anything interesting..."

YMMV.  Some people hate the construct.  I think it's pretty Pythonic.

-- 
Skip Montanaro (skip at pobox.com)
http://www.mojam.com/
http://www.musi-cal.com/




More information about the Python-list mailing list