finally — Intermediate Examples
Block that always executes after try/except, used for cleanup
finally with return
How finally interacts with return statements.
python
def test_finally(): try: print(" In try") return "from try" except: print(" In except") return "from except" finally: print(" In finally (runs before return!)") result = test_finally() print(f"Got: {result}") print() # finally can override the return value (but don't do this!) def bad_practice(): try: return 1 finally: return 2 # overrides the return from try! print(f"bad_practice() = {bad_practice()}")
Expected Output
In try In finally (runs before return!) Got: from try bad_practice() = 2
finally runs even when the try block returns. If finally also has a return, it overrides the try's return — avoid this anti-pattern.
finally for resource cleanup
Ensuring resources are released.
python
# Manual resource management with finally resources = [] def acquire(name): resources.append(name) print(f" Acquired: {name}") return name def release(name): resources.remove(name) print(f" Released: {name}") # Works even if processing fails try: r = acquire("database") print(" Processing...") raise RuntimeError("Something went wrong") except RuntimeError as e: print(f" Error: {e}") finally: if "database" in resources: release("database") print(f"Resources still held: {resources}")
Expected Output
Acquired: database Processing... Error: Something went wrong Released: database Resources still held: []
finally is the manual version of what 'with' statements automate. Use 'with' when possible, but finally is still useful for custom cleanup logic.
Want to try these examples interactively?
Open Intermediate Playground