GNU Info

Info Node: (python2.1-tut.info)Handling Exceptions

(python2.1-tut.info)Handling Exceptions


Next: Raising Exceptions Prev: Exceptions Up: Errors and Exceptions
Enter node , (file) or (file)node

Handling Exceptions
===================

It is possible to write programs that handle selected exceptions.  Look
at the following example, which asks the user for input until a valid
integer has been entered, but allows the user to interrupt the program
(using <Control-C> or whatever the operating system supports); note
that a user-generated interruption is signalled by raising the
`KeyboardInterrupt' exception.

     >>> while 1:
     ...     try:
     ...         x = int(raw_input("Please enter a number: "))
     ...         break
     ...     except ValueError:
     ...         print "Oops! That was no valid number.  Try again..."
     ...

The `try' statement works as follows.

   * First, the _try clause_ (the statement(s) between the `try' and
     `except' keywords) is executed.

   * If no exception occurs, the _except clause_ is skipped and
     execution of the `try' statement is finished.

   * If an exception occurs during execution of the try clause, the
     rest of the clause is skipped.  Then if its type matches the
     exception named after the `except' keyword, the rest of the try
     clause is skipped, the except clause is executed, and then
     execution continues after the `try' statement.

   * If an exception occurs which does not match the exception named in
     the except clause, it is passed on to outer `try' statements; if
     no handler is found, it is an _unhandled exception_ and execution
     stops with a message as shown above.


A `try' statement may have more than one except clause, to specify
handlers for different exceptions.  At most one handler will be
executed.  Handlers only handle exceptions that occur in the
corresponding try clause, not in other handlers of the same `try'
statement. An except clause may name multiple exceptions as a
parenthesized list, e.g.:

     ... except (RuntimeError, TypeError, NameError):
     ...     pass

The last except clause may omit the exception name(s), to serve as a
wildcard.  Use this with extreme caution, since it is easy to mask a
real programming error in this way!  It can also be used to print an
error message and then re-raise the exception (allowing a caller to
handle the exception as well):

     import string, sys
     
     try:
         f = open('myfile.txt')
         s = f.readline()
         i = int(string.strip(s))
     except IOError, (errno, strerror):
         print "I/O error(%s): %s" % (errno, strerror)
     except ValueError:
         print "Could not convert data to an integer."
     except:
         print "Unexpected error:", sys.exc_info()[0]
         raise

The `try' ... `except' statement has an optional _else clause_, which,
when present, must follow all except clauses.  It is useful for code
that must be executed if the try clause does not raise an exception.
For example:

     for arg in sys.argv[1:]:
         try:
             f = open(arg, 'r')
         except IOError:
             print 'cannot open', arg
         else:
             print arg, 'has', len(f.readlines()), 'lines'
             f.close()

The use of the `else' clause is better than adding additional code to
the `try' clause because it avoids accidentally catching an exception
that wasn't raised by the code being protected by the `try' ...
`except' statement.

When an exception occurs, it may have an associated value, also known as
the exception's _argument_.  The presence and type of the argument
depend on the exception type.  For exception types which have an
argument, the except clause may specify a variable after the exception
name (or list) to receive the argument's value, as follows:

     >>> try:
     ...     spam()
     ... except NameError, x:
     ...     print 'name', x, 'undefined'
     ...
     name spam undefined

If an exception has an argument, it is printed as the last part
(`detail') of the message for unhandled exceptions.

Exception handlers don't just handle exceptions if they occur
immediately in the try clause, but also if they occur inside functions
that are called (even indirectly) in the try clause.  For example:

     >>> def this_fails():
     ...     x = 1/0
     ...
     >>> try:
     ...     this_fails()
     ... except ZeroDivisionError, detail:
     ...     print 'Handling run-time error:', detail
     ...
     Handling run-time error: integer division or modulo


automatically generated by info2www version 1.2.2.9