Concepts / try...finally statements

try...finally statements

The central pattern is acquire in try, perform the required work, and release in finally.

  • Programming
Interactive lab

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

  1. Statements in try run until one raises an exception; the rest of try is skipped.
  2. Python checks the except clauses in order and runs the first one whose type matches.
  3. If nothing was raised, the else block runs instead.
  4. 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.

Educational simulation

Loading the simulation…

Interactive lab

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

  1. 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).
  2. The block runs. If a statement raises (here int() on text that is not a number), the rest of the block is skipped.
  3. 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.
  4. 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).
  5. 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.

Educational simulation

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.

Key point

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.

try blockmain worknormal completionfinally blockcleanupexecution continuesexceptionexception propagatesfinishesraisesenterenterafter cleanupafter cleanup
What happens when the try block completes normally or raises an exception, and how does execution reach the finally block?

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?

  • Only code after the complete try statement

  • The finally block

  • The try block before the resource is acquired

Reveal answer
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.

resourcenot acquiredresourceacquiredtry workuse resourceresourcereleasedtry acquiresusefinally releases
How does a resource move from acquisition in the try block to release in the finally block, even when the main work does not complete normally?
Worked example

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.

  1. 1
    Acquire

    Place the resource-acquisition action in the try block.

  2. 2
    Use

    Perform the operation that needs the resource in the try block.

  3. 3
    Release

    Place the resource-release action in the finally block so it belongs to the cleanup stage.

Result

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.

acquiretry blockacquirewith statementreleasefinally block__exit__automatic cleanupexplicit lifecyclehandled automatically
What is the difference between explicitly placing release logic in finally and allowing with to manage the lifecycle?
PatternWhere cleanup is describedMain idea
try...finallyIn the finally blockThe programmer explicitly places resource-release code in the cleanup block.
withThrough the __exit__ methodThe 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.

Key point

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 like

    The resource is acquired during cleanup instead of before the main operation.

    Why it fails

    The pattern described by the source acquires the resource in the try block and releases it in the finally block.

    Do this instead

    Keep acquisition in try and release in finally.

  • Common mistake

    Treating finally as a replacement for all exception handling.

    What it looks like

    A learner expects finally alone to describe how an exception should be handled.

    Why it fails

    The source distinguishes try...except from try...finally and discusses them as separate statement uses.

    Do this instead

    Use 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 like

    Several pieces of code manually repeat the same acquisition-and-release structure.

    Why it fails

    The source states that with helps avoid repeatedly using explicit try...finally statements because its __exit__ method handles the corresponding cleanup code.

    Do this instead

    Consider whether the resource supports the with-based pattern described in the source.

Practice the Trace

EASY

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.
Worked example

Practice Answer

Trace a resource lifecycle when the try-block operation does not complete normally.

  1. 1
    First

    The resource is acquired in the try block.

  2. 2
    Next

    The main operation runs in the try block and does not complete normally.

  3. 3
    Then

    Control reaches the finally block, where the resource-release action is placed.

Result

The resource lifecycle remains organized because the acquisition and release actions are assigned to their respective blocks.

Key Takeaways

  1. 1
    A try...finally statement organizes cleanup after work in a try block.
  2. 2
    A common resource-management pattern acquires a resource in try and releases it in finally.
  3. 3
    The finally block keeps the release action connected to leaving the try-block work.
  4. 4
    A with statement can express this resource-management pattern more cleanly.
  5. 5
    The __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.

Related concepts

More concepts starting with T