Common Exception Types
The try..except statement separates normal code (try block) from error-handling code (except blocks).
Why Exception Handling Has Separate Paths
A try..except statement separates two kinds of work: code that is expected to run normally and code that handles errors. The try block contains the normal statements. The except blocks provide responses for specified exception types. This separation lets Python follow a different execution path when a statement in the try block raises an exception.
The Try and Except Structure
A try..except statement begins with the try keyword, followed by a colon and an indented block of statements. Below that block, one or more except blocks specify exception types to catch. An optional else block can follow the except blocks and runs only when no exception occurs in the try block.
The else block is optional. It does not run after an exception is handled; it runs only when every statement in the try block completes without raising an exception.
Tracing an Exception Through the Try Block
Python begins by executing the statements inside the try block in order. If a statement raises an exception, Python immediately stops executing the remaining statements in that try block. It then checks the except blocks in the order they appear. The first except block whose exception type matches the raised exception runs. The other except blocks are skipped, the else block is skipped, and execution continues after the entire try..except statement.
What do you think happens?
Suppose the first statement in a try block raises an exception. What happens to the later statements in that same try block?
Reveal answer
Answer: They are skipped, and Python checks the except blocks.
Python immediately stops executing the rest of the try block when a statement raises an exception. It then checks the except blocks in order.
Choosing the First Matching Handler
Input Cancellation and End of Input
Trace the source example in which an input operation may raise EOFError or KeyboardInterrupt.
Normal input: The input operation completes without either of the two listed exceptions. The except blocks are skipped, and the else block runs to print what the user entered.
End-of-file signal: If the user presses Ctrl+D, or Ctrl+Z on Windows, the raw_input call raises EOFError. Python selects the first except block because it matches EOFError.
Cancellation signal: If the user presses Ctrl+C, a KeyboardInterrupt is raised. Python skips the first handler, selects the second except block, and runs its custom message.
Another exception: If an exception other than the listed types occurs, neither of those except blocks matches. If no exception occurs, the except blocks are also skipped.
The selected path depends on what happens during the input operation: the else path is used for normal completion, while the first matching specific handler is used for EOFError or KeyboardInterrupt.
Place except blocks from most specific to most general. Because Python checks them in order and stops at the first match, a general handler placed first can catch everything and prevent more specific handlers below it from running.
Mistakes in Exception Flow
Expecting the rest of the try block to continue after an exception.
Python immediately stops executing the remaining statements in the try block.
Fix:
Trace from the raising statement directly to the except-block checks.Expecting every except block to run.
Python runs only the first except block whose exception type matches and skips the others.
Fix:
Check the handlers from top to bottom and stop at the first match.Expecting else to run after an exception is handled.
The else block runs only when no exception occurs in the try block.
Fix:
Use the else path only for successful completion of the try block.Putting a general exception handler before a specific handler.
The general handler can match first, so the more specific handler below it never runs.
Fix:
Order handlers from most specific to most general.
Practice the Execution Path
For the source input example, describe the path for each situation: normal user input, Ctrl+D or Ctrl+Z on Windows, Ctrl+C, and an exception other than EOFError or KeyboardInterrupt.
Hints
- First decide whether the try block completes without an exception.
- If an exception occurs, identify its type and check the except blocks from top to bottom.
- Remember that the else block runs only on the no-exception path.
- Normal input follows the try block to the else block.
- EOFError selects the first matching handler.
- KeyboardInterrupt skips the first nonmatching handler and selects the second matching handler.
- A raised exception stops the remaining try statements and skips else.
- Handlers are checked in written order, so specific handlers belong before general ones.
Key Takeaways
- A try block contains normal code, while except blocks contain error-handling paths for specified exception types.
- When a statement in the try block raises an exception, Python stops the rest of that try block and checks except blocks in order.
- Only the first matching except block runs; the remaining handlers are skipped.
- The optional else block runs only when the try block completes without an exception.
- Put specific exception handlers before general handlers so the intended specific handler can run.