I l@ve RuBoard Previous Section Next Section

7.3 Exception Idioms

We've seen the mechanics behind exceptions; now, let's take look at some of the ways they're typically used.

7.3.1 Exceptions Aren't Always a Bad Thing

Python raises exceptions on errors, but not all exceptions are errors. For instance, we saw in Chapter 2, that file object read methods return empty strings at the end of a file. Python also provides a built-in function called raw_input for reading from the standard input stream; unlike file methods, raw_input raises the built-in EOFError at end of file, instead of returning an empty string (an empty string means an empty line when raw_input is used). Because of that, raw_input often appears wrapped in a try handler and nested in a loop, as in the following code

while 1:
    try:
        line = raw_input()     # read line from stdin
    except EOFError:
        break                  # exit loop at end of file
    else:
            Process next 'line' here

7.3.2 Searches Sometimes Signal Success by raise

User-defined exceptions can signal nonerror conditions also. For instance, a search routine can be coded to raise an exception when a match is found, instead of returning a status flag that must be interpreted by the caller. In the following, the try/except/else exception handler does the work of an if/else return value tester:

Found = "Item found"

def searcher():
    raise Found or return
try:
    searcher()
except Found:              # exception if item was found
    Success
else:                      # else returned: not found
    Failure

7.3.3 Outer try Statements Can Debug Code

You can also make use of exception handlers to replace Python's default top-level exception-handling behavior seen previously. By wrapping an entire program (or a call to it) in an outer try, you can catch any exception that may occur while your program runs, thereby subverting the default program termination. In the following, the empty except clause catches any uncaught exception raised while the program runs. To get hold of the actual exception that occurred, fetch the exc_type and exc_value attributes from the built-in sys module; they're automatically set to the current exception's name and extra data:[4]

[4] By the way, the built-in traceback module allows the current exception to be processed in a generic fashion, and as of Python 1.5.1, a new sys.exc_info() function returns a tuple containing the current exception's type, data, and traceback. sys.exc_type and sys.exc_value still work, but manage a single, global exception; exc_info() keeps track of each thread's exception information and so is thread-specific. This distinction matters only when using multiple threads in Python programs (a subject beyond this book's scope). See the Python library manual for more details.

try:
    Run program
except:              # all uncaught exceptions come here
    import sys
    print 'uncaught!', sys.exc_type, sys.exc_value
I l@ve RuBoard Previous Section Next Section