annotate Doc/tutorial/errors.rst @ 49955:878d40468c4e legacy-trunk

Issue #4384: Added logging integration with warnings module using captureWarnings(). This change includes a NullHandler which does nothing; it will be of use to library developers who want to avoid the "No handlers could be found for logger XXX" message which can appear if the library user doesn't configure logging.
author Vinay Sajip <vinay_sajip@yahoo.co.uk>
date Wed, 03 Dec 2008 23:22:58 +0000
parents d17cc4d1766c
children ee9ced92843a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
42603
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
1 .. _tut-errors:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
2
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
3 *********************
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
4 Errors and Exceptions
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
5 *********************
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
6
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
7 Until now error messages haven't been more than mentioned, but if you have tried
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
8 out the examples you have probably seen some. There are (at least) two
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
9 distinguishable kinds of errors: *syntax errors* and *exceptions*.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
10
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
11
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
12 .. _tut-syntaxerrors:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
13
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
14 Syntax Errors
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
15 =============
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
16
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
17 Syntax errors, also known as parsing errors, are perhaps the most common kind of
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
18 complaint you get while you are still learning Python::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
19
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
20 >>> while True print 'Hello world'
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
21 File "<stdin>", line 1, in ?
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
22 while True print 'Hello world'
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
23 ^
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
24 SyntaxError: invalid syntax
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
25
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
26 The parser repeats the offending line and displays a little 'arrow' pointing at
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
27 the earliest point in the line where the error was detected. The error is
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
28 caused by (or at least detected at) the token *preceding* the arrow: in the
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
29 example, the error is detected at the keyword :keyword:`print`, since a colon
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
30 (``':'``) is missing before it. File name and line number are printed so you
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
31 know where to look in case the input came from a script.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
32
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
33
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
34 .. _tut-exceptions:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
35
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
36 Exceptions
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
37 ==========
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
38
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
39 Even if a statement or expression is syntactically correct, it may cause an
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
40 error when an attempt is made to execute it. Errors detected during execution
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
41 are called *exceptions* and are not unconditionally fatal: you will soon learn
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
42 how to handle them in Python programs. Most exceptions are not handled by
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
43 programs, however, and result in error messages as shown here::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
44
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
45 >>> 10 * (1/0)
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
46 Traceback (most recent call last):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
47 File "<stdin>", line 1, in ?
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
48 ZeroDivisionError: integer division or modulo by zero
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
49 >>> 4 + spam*3
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
50 Traceback (most recent call last):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
51 File "<stdin>", line 1, in ?
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
52 NameError: name 'spam' is not defined
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
53 >>> '2' + 2
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
54 Traceback (most recent call last):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
55 File "<stdin>", line 1, in ?
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
56 TypeError: cannot concatenate 'str' and 'int' objects
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
57
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
58 The last line of the error message indicates what happened. Exceptions come in
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
59 different types, and the type is printed as part of the message: the types in
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
60 the example are :exc:`ZeroDivisionError`, :exc:`NameError` and :exc:`TypeError`.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
61 The string printed as the exception type is the name of the built-in exception
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
62 that occurred. This is true for all built-in exceptions, but need not be true
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
63 for user-defined exceptions (although it is a useful convention). Standard
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
64 exception names are built-in identifiers (not reserved keywords).
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
65
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
66 The rest of the line provides detail based on the type of exception and what
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
67 caused it.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
68
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
69 The preceding part of the error message shows the context where the exception
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
70 happened, in the form of a stack traceback. In general it contains a stack
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
71 traceback listing source lines; however, it will not display lines read from
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
72 standard input.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
73
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
74 :ref:`bltin-exceptions` lists the built-in exceptions and their meanings.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
75
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
76
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
77 .. _tut-handling:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
78
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
79 Handling Exceptions
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
80 ===================
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
81
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
82 It is possible to write programs that handle selected exceptions. Look at the
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
83 following example, which asks the user for input until a valid integer has been
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
84 entered, but allows the user to interrupt the program (using :kbd:`Control-C` or
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
85 whatever the operating system supports); note that a user-generated interruption
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
86 is signalled by raising the :exc:`KeyboardInterrupt` exception. ::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
87
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
88 >>> while True:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
89 ... try:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
90 ... x = int(raw_input("Please enter a number: "))
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
91 ... break
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
92 ... except ValueError:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
93 ... print "Oops! That was no valid number. Try again..."
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
94 ...
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
95
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
96 The :keyword:`try` statement works as follows.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
97
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
98 * First, the *try clause* (the statement(s) between the :keyword:`try` and
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
99 :keyword:`except` keywords) is executed.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
100
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
101 * If no exception occurs, the *except clause* is skipped and execution of the
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
102 :keyword:`try` statement is finished.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
103
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
104 * If an exception occurs during execution of the try clause, the rest of the
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
105 clause is skipped. Then if its type matches the exception named after the
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
106 :keyword:`except` keyword, the except clause is executed, and then execution
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
107 continues after the :keyword:`try` statement.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
108
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
109 * If an exception occurs which does not match the exception named in the except
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
110 clause, it is passed on to outer :keyword:`try` statements; if no handler is
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
111 found, it is an *unhandled exception* and execution stops with a message as
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
112 shown above.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
113
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
114 A :keyword:`try` statement may have more than one except clause, to specify
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
115 handlers for different exceptions. At most one handler will be executed.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
116 Handlers only handle exceptions that occur in the corresponding try clause, not
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
117 in other handlers of the same :keyword:`try` statement. An except clause may
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
118 name multiple exceptions as a parenthesized tuple, for example::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
119
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
120 ... except (RuntimeError, TypeError, NameError):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
121 ... pass
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
122
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
123 The last except clause may omit the exception name(s), to serve as a wildcard.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
124 Use this with extreme caution, since it is easy to mask a real programming error
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
125 in this way! It can also be used to print an error message and then re-raise
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
126 the exception (allowing a caller to handle the exception as well)::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
127
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
128 import sys
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
129
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
130 try:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
131 f = open('myfile.txt')
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
132 s = f.readline()
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
133 i = int(s.strip())
45048
250f29bab61b Demonstrate new except/as syntax.
Raymond Hettinger <python@rcn.com>
parents: 44315
diff changeset
134 except IOError as (errno, strerror):
47282
70f9a5db279c update the tutorial to use str.format
Benjamin Peterson <benjamin@python.org>
parents: 45048
diff changeset
135 print "I/O error({0}): {1}".format(errno, strerror)
42603
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
136 except ValueError:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
137 print "Could not convert data to an integer."
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
138 except:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
139 print "Unexpected error:", sys.exc_info()[0]
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
140 raise
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
141
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
142 The :keyword:`try` ... :keyword:`except` statement has an optional *else
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
143 clause*, which, when present, must follow all except clauses. It is useful for
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
144 code that must be executed if the try clause does not raise an exception. For
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
145 example::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
146
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
147 for arg in sys.argv[1:]:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
148 try:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
149 f = open(arg, 'r')
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
150 except IOError:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
151 print 'cannot open', arg
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
152 else:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
153 print arg, 'has', len(f.readlines()), 'lines'
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
154 f.close()
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
155
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
156 The use of the :keyword:`else` clause is better than adding additional code to
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
157 the :keyword:`try` clause because it avoids accidentally catching an exception
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
158 that wasn't raised by the code being protected by the :keyword:`try` ...
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
159 :keyword:`except` statement.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
160
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
161 When an exception occurs, it may have an associated value, also known as the
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
162 exception's *argument*. The presence and type of the argument depend on the
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
163 exception type.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
164
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
165 The except clause may specify a variable after the exception name (or tuple).
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
166 The variable is bound to an exception instance with the arguments stored in
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
167 ``instance.args``. For convenience, the exception instance defines
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
168 :meth:`__getitem__` and :meth:`__str__` so the arguments can be accessed or
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
169 printed directly without having to reference ``.args``.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
170
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
171 But use of ``.args`` is discouraged. Instead, the preferred use is to pass a
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
172 single argument to an exception (which can be a tuple if multiple arguments are
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
173 needed) and have it bound to the ``message`` attribute. One may also
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
174 instantiate an exception first before raising it and add any attributes to it as
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
175 desired. ::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
176
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
177 >>> try:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
178 ... raise Exception('spam', 'eggs')
45048
250f29bab61b Demonstrate new except/as syntax.
Raymond Hettinger <python@rcn.com>
parents: 44315
diff changeset
179 ... except Exception as inst:
42603
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
180 ... print type(inst) # the exception instance
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
181 ... print inst.args # arguments stored in .args
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
182 ... print inst # __str__ allows args to printed directly
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
183 ... x, y = inst # __getitem__ allows args to be unpacked directly
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
184 ... print 'x =', x
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
185 ... print 'y =', y
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
186 ...
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
187 <type 'exceptions.Exception'>
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
188 ('spam', 'eggs')
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
189 ('spam', 'eggs')
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
190 x = spam
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
191 y = eggs
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
192
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
193 If an exception has an argument, it is printed as the last part ('detail') of
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
194 the message for unhandled exceptions.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
195
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
196 Exception handlers don't just handle exceptions if they occur immediately in the
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
197 try clause, but also if they occur inside functions that are called (even
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
198 indirectly) in the try clause. For example::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
199
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
200 >>> def this_fails():
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
201 ... x = 1/0
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
202 ...
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
203 >>> try:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
204 ... this_fails()
45048
250f29bab61b Demonstrate new except/as syntax.
Raymond Hettinger <python@rcn.com>
parents: 44315
diff changeset
205 ... except ZeroDivisionError as detail:
42603
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
206 ... print 'Handling run-time error:', detail
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
207 ...
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
208 Handling run-time error: integer division or modulo by zero
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
209
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
210
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
211 .. _tut-raising:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
212
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
213 Raising Exceptions
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
214 ==================
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
215
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
216 The :keyword:`raise` statement allows the programmer to force a specified
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
217 exception to occur. For example::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
218
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
219 >>> raise NameError, 'HiThere'
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
220 Traceback (most recent call last):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
221 File "<stdin>", line 1, in ?
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
222 NameError: HiThere
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
223
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
224 The first argument to :keyword:`raise` names the exception to be raised. The
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
225 optional second argument specifies the exception's argument. Alternatively, the
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
226 above could be written as ``raise NameError('HiThere')``. Either form works
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
227 fine, but there seems to be a growing stylistic preference for the latter.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
228
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
229 If you need to determine whether an exception was raised but don't intend to
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
230 handle it, a simpler form of the :keyword:`raise` statement allows you to
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
231 re-raise the exception::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
232
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
233 >>> try:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
234 ... raise NameError, 'HiThere'
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
235 ... except NameError:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
236 ... print 'An exception flew by!'
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
237 ... raise
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
238 ...
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
239 An exception flew by!
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
240 Traceback (most recent call last):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
241 File "<stdin>", line 2, in ?
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
242 NameError: HiThere
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
243
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
244
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
245 .. _tut-userexceptions:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
246
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
247 User-defined Exceptions
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
248 =======================
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
249
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
250 Programs may name their own exceptions by creating a new exception class.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
251 Exceptions should typically be derived from the :exc:`Exception` class, either
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
252 directly or indirectly. For example::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
253
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
254 >>> class MyError(Exception):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
255 ... def __init__(self, value):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
256 ... self.value = value
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
257 ... def __str__(self):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
258 ... return repr(self.value)
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
259 ...
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
260 >>> try:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
261 ... raise MyError(2*2)
45048
250f29bab61b Demonstrate new except/as syntax.
Raymond Hettinger <python@rcn.com>
parents: 44315
diff changeset
262 ... except MyError as e:
42603
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
263 ... print 'My exception occurred, value:', e.value
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
264 ...
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
265 My exception occurred, value: 4
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
266 >>> raise MyError, 'oops!'
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
267 Traceback (most recent call last):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
268 File "<stdin>", line 1, in ?
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
269 __main__.MyError: 'oops!'
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
270
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
271 In this example, the default :meth:`__init__` of :class:`Exception` has been
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
272 overridden. The new behavior simply creates the *value* attribute. This
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
273 replaces the default behavior of creating the *args* attribute.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
274
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
275 Exception classes can be defined which do anything any other class can do, but
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
276 are usually kept simple, often only offering a number of attributes that allow
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
277 information about the error to be extracted by handlers for the exception. When
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
278 creating a module that can raise several distinct errors, a common practice is
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
279 to create a base class for exceptions defined by that module, and subclass that
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
280 to create specific exception classes for different error conditions::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
281
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
282 class Error(Exception):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
283 """Base class for exceptions in this module."""
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
284 pass
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
285
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
286 class InputError(Error):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
287 """Exception raised for errors in the input.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
288
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
289 Attributes:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
290 expression -- input expression in which the error occurred
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
291 message -- explanation of the error
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
292 """
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
293
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
294 def __init__(self, expression, message):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
295 self.expression = expression
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
296 self.message = message
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
297
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
298 class TransitionError(Error):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
299 """Raised when an operation attempts a state transition that's not
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
300 allowed.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
301
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
302 Attributes:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
303 previous -- state at beginning of transition
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
304 next -- attempted new state
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
305 message -- explanation of why the specific transition is not allowed
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
306 """
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
307
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
308 def __init__(self, previous, next, message):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
309 self.previous = previous
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
310 self.next = next
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
311 self.message = message
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
312
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
313 Most exceptions are defined with names that end in "Error," similar to the
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
314 naming of the standard exceptions.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
315
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
316 Many standard modules define their own exceptions to report errors that may
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
317 occur in functions they define. More information on classes is presented in
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
318 chapter :ref:`tut-classes`.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
319
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
320
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
321 .. _tut-cleanup:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
322
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
323 Defining Clean-up Actions
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
324 =========================
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
325
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
326 The :keyword:`try` statement has another optional clause which is intended to
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
327 define clean-up actions that must be executed under all circumstances. For
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
328 example::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
329
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
330 >>> try:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
331 ... raise KeyboardInterrupt
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
332 ... finally:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
333 ... print 'Goodbye, world!'
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
334 ...
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
335 Goodbye, world!
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
336 Traceback (most recent call last):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
337 File "<stdin>", line 2, in ?
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
338 KeyboardInterrupt
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
339
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
340 A *finally clause* is always executed before leaving the :keyword:`try`
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
341 statement, whether an exception has occurred or not. When an exception has
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
342 occurred in the :keyword:`try` clause and has not been handled by an
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
343 :keyword:`except` clause (or it has occurred in a :keyword:`except` or
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
344 :keyword:`else` clause), it is re-raised after the :keyword:`finally` clause has
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
345 been executed. The :keyword:`finally` clause is also executed "on the way out"
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
346 when any other clause of the :keyword:`try` statement is left via a
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
347 :keyword:`break`, :keyword:`continue` or :keyword:`return` statement. A more
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
348 complicated example (having :keyword:`except` and :keyword:`finally` clauses in
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
349 the same :keyword:`try` statement works as of Python 2.5)::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
350
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
351 >>> def divide(x, y):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
352 ... try:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
353 ... result = x / y
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
354 ... except ZeroDivisionError:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
355 ... print "division by zero!"
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
356 ... else:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
357 ... print "result is", result
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
358 ... finally:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
359 ... print "executing finally clause"
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
360 ...
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
361 >>> divide(2, 1)
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
362 result is 2
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
363 executing finally clause
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
364 >>> divide(2, 0)
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
365 division by zero!
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
366 executing finally clause
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
367 >>> divide("2", "1")
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
368 executing finally clause
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
369 Traceback (most recent call last):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
370 File "<stdin>", line 1, in ?
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
371 File "<stdin>", line 3, in divide
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
372 TypeError: unsupported operand type(s) for /: 'str' and 'str'
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
373
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
374 As you can see, the :keyword:`finally` clause is executed in any event. The
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
375 :exc:`TypeError` raised by dividing two strings is not handled by the
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
376 :keyword:`except` clause and therefore re-raised after the :keyword:`finally`
49207
d17cc4d1766c Fix typo.
Georg Brandl <georg@python.org>
parents: 47282
diff changeset
377 clause has been executed.
42603
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
378
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
379 In real world applications, the :keyword:`finally` clause is useful for
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
380 releasing external resources (such as files or network connections), regardless
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
381 of whether the use of the resource was successful.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
382
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
383
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
384 .. _tut-cleanup-with:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
385
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
386 Predefined Clean-up Actions
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
387 ===========================
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
388
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
389 Some objects define standard clean-up actions to be undertaken when the object
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
390 is no longer needed, regardless of whether or not the operation using the object
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
391 succeeded or failed. Look at the following example, which tries to open a file
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
392 and print its contents to the screen. ::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
393
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
394 for line in open("myfile.txt"):
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
395 print line
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
396
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
397 The problem with this code is that it leaves the file open for an indeterminate
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
398 amount of time after the code has finished executing. This is not an issue in
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
399 simple scripts, but can be a problem for larger applications. The
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
400 :keyword:`with` statement allows objects like files to be used in a way that
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
401 ensures they are always cleaned up promptly and correctly. ::
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
402
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
403 with open("myfile.txt") as f:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
404 for line in f:
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
405 print line
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
406
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
407 After the statement is executed, the file *f* is always closed, even if a
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
408 problem was encountered while processing the lines. Other objects which provide
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
409 predefined clean-up actions will indicate this in their documentation.
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
410
c62f6669ae22 Move the 2.6 reST doc tree in place.
Georg Brandl <georg@python.org>
parents:
diff changeset
411