| An Introduction to Python by Guido van Rossum and Fred L. Drake, Jr. Paperback (6"x9"), 124 pages ISBN 0954161769 RRP £12.95 ($19.95) Sales of this book support the Python Software Foundation! Get a printed copy>>> |
8.3 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 True:
... try:
... x = int(raw_input("Enter a number: "))
... break
... except ValueError:
... print "Not a valid number. Try again..."
...
The try statement works as follows.
-
First, the try clause (the statement(s) between the
tryandexceptkeywords) is executed. -
If no exception occurs, the except clause is skipped and
execution of the
trystatement 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
exceptkeyword, the except clause is executed, and then execution continues after thetrystatement. -
If an exception occurs which does not match the exception named in the
except clause, it is passed on to outer
trystatements; 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 tuple, for example:
... 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 sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
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.
The except clause may specify a variable after the exception name (or tuple).
The variable is bound to an exception instance with the arguments stored
in instance.args. For convenience, the exception instance
defines __getitem__ and __str__ so the arguments can
be accessed or printed directly without having to reference .args.
But use of .args is discouraged. Instead, the preferred use is to pass
a single argument to an exception (which can be a tuple if multiple arguments
are needed) and have it bound to the message attribute. One my also
instantiate an exception first before raising it and add any attributes to it
as desired.
>>> try:
... raise Exception('spam', 'eggs')
... except Exception, inst:
... print type(inst) # the exception instance
... print inst.args # arguments stored in .args
... print inst # __str__ allows args to
# printed directly
... x, y = inst # __getitem__ allows args
# to be unpacked directly
... print 'x =', x
... print 'y =', y
...
<type 'instance'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
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 by zero
| ISBN 0954161769 | An Introduction to Python | See the print edition |