Raising Exceptions
The try..except statement separates normal code (try block) from error-handling code (except blocks).
When Normal Execution Breaks
A try..except statement separates two responsibilities. The try block contains code that Python should attempt to execute normally. The except blocks contain the error-handling code used if an exception is raised. This separation lets a program respond to particular exceptions instead of treating normal execution and error handling as one undifferentiated sequence.
What do you think happens?
A try block contains several statements. If one statement raises an exception, what happens to the statements that follow it inside the same try block?
Reveal answer
Answer: They are skipped and Python checks the except blocks.
When a statement in the try block raises an exception, Python immediately stops executing the rest of that try block and checks the except blocks in order.
The Execution Path
Python begins with the statements inside the try block and executes them in order. If every statement completes without raising an exception, Python skips the except blocks. If an else block is present, Python then runs it. If a statement raises an exception, Python stops the try block immediately, so later statements in that block do not run. Python checks the except blocks and executes the first one whose exception type matches. After that matching except block finishes, the else block is skipped and execution continues after the entire try..except statement.
Statement Structure
The try..except structure starts with the try keyword, a colon, and an indented block of statements. One or more except blocks follow. Each except block specifies an exception type to catch and contains the handling statements for that type. An optional else block can follow the except blocks and runs only when the try block completes without an exception.
Choosing a Handler
Multiple except blocks are checked in the order in which they appear. Python compares the raised exception with the type specified by the first except block. If they match, that handler runs and every later except block is skipped. If they do not match, Python checks the next except block. This continues until a matching handler is found. If no listed handler matches, the except blocks described here are skipped. Because only the first matching handler runs, handlers should be ordered from most specific to most general.
Place a more specific exception handler before a more general one. A general handler placed first can match everything covered by the later specific handlers, making those later handlers unreachable during the matching process.
Input Events in Practice
Tracing different input outcomes
A program asks the user to enter something. It has one except block for EOFError, a second except block for KeyboardInterrupt, and an else block that prints the entered value.
Normal input: The input operation completes without raising an exception. Both 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 input operation raises EOFError. Python stops the try block, selects the first matching except block, and skips the second except block and the else block.
Cancellation signal: If the user presses Ctrl+C, a KeyboardInterrupt is raised. The EOFError handler does not match, so Python checks the next except block and runs the KeyboardInterrupt handler. The else block is skipped.
Another exception: If a different exception occurs, neither of these two specific except blocks matches. The two handlers and the else block are skipped.
The same try..except structure provides three distinct paths: successful input through else, end-of-file handling through the EOFError handler, and cancellation handling through the KeyboardInterrupt handler.
| Try block outcome | Except blocks | Else block | Next execution point |
|---|---|---|---|
| No exception | All skipped | Runs | After the try..except statement |
| Matching exception | First matching block runs; later blocks are skipped | Skipped | After the try..except statement |
| Exception with no listed match | Listed blocks are skipped | Skipped | Not handled by those listed blocks |
Mistakes in Handler Order
Putting a general exception handler before a more specific handler.
Python checks handlers in order. The general handler can catch the exception before Python reaches the specific handler.
Fix:
Order multiple except blocks from most specific to most general.Assuming statements after the raising statement inside the try block will still run.
Python immediately stops executing the rest of the try block when an exception is raised.
Fix:
Trace from the raising statement directly to the except-block matching process.Expecting the else block to run after an exception is handled.
The else block runs only if no exception occurs in the try block.
Fix:
Treat else as the successful, no-exception path.
Trace It Yourself
Suppose a try block contains three statements. The first completes normally, the second raises KeyboardInterrupt, and the third would normally produce a result. There are two except blocks: the first catches EOFError and the second catches KeyboardInterrupt, followed by an else block. Trace the order of execution. Identify which statement is the first skipped statement, which except block runs, whether the else block runs, and where execution continues afterward.
Hints
- Stop tracing the try block at the statement that raises the exception.
- Check the except blocks from top to bottom.
- The else block requires the try block to complete without an exception.
Key Takeaways
- The try block contains statements expected to execute normally; except blocks contain exception-specific handling.
- When a statement raises an exception, the rest of the try block is skipped immediately.
- Python checks multiple except blocks in order and runs only the first matching handler.
- The optional else block runs only when the try block completes without raising an exception.
- Order handlers from most specific to most general so that specific handlers can be reached.
Key Takeaways
- try..except separates normal execution from error handling.
- An exception stops the remaining statements in the try block.
- Except blocks are checked from top to bottom, and only the first matching block runs.
- else represents the no-exception path and is skipped when an exception occurs.
- Specific exception handlers should appear before general handlers.