flowchart TD
A["try body"] --> B{"did it raise?"}
B -->|no| C["else"]
B -->|"yes, a matching type"| D["except"]
B -->|"yes, unmatched"| E["propagates on"]
C --> F["finally"]
D --> F
E --> F
F --> G["and only then does the exception continue, or the function return"]
H["a return in the try body"] --> F
I["else is NOT the same as putting it at the end of try"] --> J["code there is no longer guarded by except"]
else in try/except
else runs only if no exception occurred.
try:
x = int("42")
except ValueError:
print("Invalid number")
else:
print("Parsed successfully:", x)finally in try/except
finally runs always (success or error). This is useful for cleanup.
f = None
try:
f = open("data.txt", "r")
print(f.read())
except FileNotFoundError:
print("File not found")
finally:
if f is not None:
f.close()
print("File closed")Prefer context managers when possible
Instead of manual .close(), use with.
try:
with open("data.txt", "r") as f:
print(f.read())
except FileNotFoundError:
print("File not found")When is finally important?
- closing files
- releasing locks
- closing DB connections
- cleaning up temporary files
Check yourself
A function raises inside `try` and has `return 'done'` inside `finally`. What does the caller see?
Verified: the ValueError vanished entirely, with no traceback and nothing logged. Python 3.14 now warns at compile time — SyntaxWarning: 'return' in a 'finally' block.
Show answer
B — `'done'` — the exception is discarded — Verified: the ValueError vanished entirely, with no traceback and nothing logged. Python 3.14 now warns at compile time — SyntaxWarning: 'return' in a 'finally' block.
When does the `else` clause of a `try` statement run?
`else` is the no-exception path. Putting that code at the end of `try` instead would leave it guarded by the `except`, so an unrelated error in it would be caught by a handler meant for the risky call.
Show answer
C — Only when the `try` body did NOT raise — `else` is the no-exception path. Putting that code at the end of `try` instead would leave it guarded by the `except`, so an unrelated error in it would be caught by a handler meant for the risky call.
With no exception raised, which blocks run and in what order?
Verified. With an exception it is `try`, `except`, `finally` instead — `finally` runs on every path.
Show answer
B — `try`, `else`, `finally` — Verified. With an exception it is `try`, `except`, `finally` instead — `finally` runs on every path.
What should `finally` be used for?
Releasing a lock, closing a handle, restoring state. Changing what the function returns from there is what silently swallows exceptions.
Show answer
B — Cleanup that must happen on every path — Releasing a lock, closing a handle, restoring state. Changing what the function returns from there is what silently swallows exceptions.
🧪 Try It Yourself
Exercise 1 – The else Clause
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 2 – The finally Clause
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 3 – else + finally Together
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.