We’ve seen the mechanics behind exceptions; now, let’s take look at some of the ways they’re typically used.
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
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
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:[53]
try:
Run program
except: # all uncaught exceptions come here import sys print 'uncaught!', sys.exc_type, sys.exc_value
[53] 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.