try...finally statements
The central pattern is acquire in try, perform the required work, and release in finally.
Try it: try / except / else / finally
How an exception jumps out of a try block to the first matching except clause, when else runs, and why finally always runs.
How it works
- Statements in try run until one raises an exception; the rest of try is skipped.
- Python checks the except clauses in order and runs the first one whose type matches.
- If nothing was raised, the else block runs instead.
- finally runs in every case.
Default run (9 steps): Call safe_divide('4'). … Return 25.0. Output was: Worked: 25.0 / Done.
Simplified: One fixed function; int() and / are modelled exactly (including how Python prints floats), but nothing is executed as Python.
Loading the simulation…
Try it: Context Managers and the with Statement
What with really does: it calls __enter__ before the block and __exit__ after it — even when an exception leaves the block — so a file opened with with is always closed before the exception continues; try/finally gives the same guarantee by hand, a bare close() is skipped by the exception, and a context manager whose __exit__ returns True suppresses the exception.
How it works
- with EXPR as f: evaluates EXPR (e.g. open(...)), calls its __enter__() and binds the returned value to f (a file's __enter__ returns the file itself).
- The block runs. If a statement raises (here int() on text that is not a number), the rest of the block is skipped.
- Whether the block finished or an exception is leaving it, Python calls __exit__(exc_type, exc, tb) — for a file this closes it. This happens before any outer except sees the exception.
- If __exit__ returns a true value the exception is suppressed and execution continues after the block; a file's __exit__ returns None, so the exception propagates to the nearest matching except (or stops the program).
- try: … finally: f.close() gives the same cleanup by hand (start with f = None and check it); open() … f.close() without either leaves the file open when an exception jumps past close().
Default run (10 steps): The program opens data.txt, which contains '4x\n'. Watch when the file is closed — and what happens if int() raises ValueError. … The program finished. The file was closed.
Simplified: Fixed program templates reading one line of data.txt (text you type, up to 12 ASCII characters) and converting it with int(). A small interpreter written for these statements runs them — nothing is executed — and it reproduces CPython 3.12's sys.settrace line/call/exception events, printed output, final error line and file state for every combination. File objects' own __enter__/__exit__ are C code, so they appear as protocol steps rather than traced lines.
Loading the simulation…
Why Cleanup Needs a Plan
Some operations temporarily acquire a resource. A program may need to release that resource afterward, including when the main operation does not complete as expected. A try...finally statement provides a structure for placing the release action in a finally block after the resource is acquired in the try block.
The central pattern is acquire in try, perform the required work, and release in finally.
Tracing the Control Flow
Control first enters the try block. When the try block finishes, execution reaches the finally block. The finally block is the place for the action that must be carried out as the try-block work is being left, such as releasing a resource. This makes the cleanup part of the control-flow structure rather than an action that depends on remembering a separate call later.
What do you think happens?
A resource is acquired in the try block, and the work in that block raises an exception. Which part is responsible for the release action?
Reveal answer
The finally block
The common pattern places resource acquisition in the try block and resource release in the finally block, so the release action is associated with leaving the try-block work.
The Resource Lifecycle
A resource-management pattern has two connected stages. First, the program acquires the resource inside the try block. Next, after the try-block work is left, the program releases the resource inside the finally block. The value of this arrangement is that acquisition and release remain visibly connected in one statement structure.
A Resource That Must Be Released
A program needs to acquire a resource, use it during its main operation, and release it after the try-block work.
- 1Acquire
Place the resource-acquisition action in the try block.
- 2Use
Perform the operation that needs the resource in the try block.
- 3Release
Place the resource-release action in the finally block so it belongs to the cleanup stage.
The structure clearly separates the main operation from the release action while keeping both actions in one control-flow pattern.
Choosing with Instead
The try...finally pattern is useful, but the same kind of resource lifecycle can be expressed with a with statement. The source describes with as a way to perform this pattern in a clean manner. Its __exit__ method takes care of the code that would otherwise have been written in a finally block.
| Pattern | Where cleanup is described | Main idea |
|---|---|---|
| try...finally | In the finally block | The programmer explicitly places resource-release code in the cleanup block. |
| with | Through the __exit__ method | The cleanup corresponding to the finally-block code is handled automatically. |
Both patterns organize resource cleanup; with reduces the need to repeat explicit try...finally structures.
Use the try...finally pattern to understand the lifecycle explicitly. When a suitable with-based resource interface is available, with can provide the cleaner form described by the source.
Mistakes Beginners Make
Common mistake Putting resource acquisition only in the finally block.
What it looks likeThe resource is acquired during cleanup instead of before the main operation.
Why it failsThe pattern described by the source acquires the resource in the try block and releases it in the finally block.
Do this insteadKeep acquisition in try and release in finally.
Common mistake Treating finally as a replacement for all exception handling.
What it looks likeA learner expects finally alone to describe how an exception should be handled.
Why it failsThe source distinguishes try...except from try...finally and discusses them as separate statement uses.
Do this insteadUse finally for the cleanup stage and learn try...except separately for exception-handling behavior.
Common mistake Repeating explicit try...finally code when a with statement can manage the resource lifecycle.
What it looks likeSeveral pieces of code manually repeat the same acquisition-and-release structure.
Why it failsThe source states that with helps avoid repeatedly using explicit try...finally statements because its
__exit__method handles the corresponding cleanup code.Do this insteadConsider whether the resource supports the with-based pattern described in the source.
Practice the Trace
A program acquires a resource in a try block. The main operation then raises an exception. Describe the order of the two important stages: the main operation and the release action. Then explain why placing the release action in finally is useful.
Hints
- Identify where acquisition occurs.
- Identify where release occurs.
- Think about which block owns the cleanup action.
Practice Answer
Trace a resource lifecycle when the try-block operation does not complete normally.
- 1First
The resource is acquired in the try block.
- 2Next
The main operation runs in the try block and does not complete normally.
- 3Then
Control reaches the finally block, where the resource-release action is placed.
The resource lifecycle remains organized because the acquisition and release actions are assigned to their respective blocks.
Key Takeaways
- 1A try...finally statement organizes cleanup after work in a try block.
- 2A common resource-management pattern acquires a resource in try and releases it in finally.
- 3The finally block keeps the release action connected to leaving the try-block work.
- 4A with statement can express this resource-management pattern more cleanly.
- 5The
__exit__method handles the code that would otherwise be written in a finally block.
At a glance
- try...finally separates the main operation from its cleanup action.
- The common resource pattern is acquisition in try followed by release in finally.
- The cleanup action belongs in finally rather than being left to a later, separately remembered step.
- The with statement and its
__exit__method can manage this lifecycle automatically and cleanly.