A finally clause runs after the try clause and any matching except or else clause, regardless of whether an exception occurred. Place it last in the complete try...except...else...finally statement when follow-up work must happen in every outcome. section 12.4.2 section 12.6
Use finally when processing needs an unconditional final action:
- Put code that should run after successful or unsuccessful processing in finally, such as notifying users that processing is done. section 12.4.2
- Place finally after else when both clauses appear; otherwise, place it after except. section 12.4.2
- Expect finally to run before break, continue, or return transfers control away from the try or exception-handling clauses. section 12.4.2
Listing 12.14 Using the finally clause in the try...except statement
def process_task_string8(text):
title, urgency_str = text.split(",")
try:
urgency = int(urgency_str)
except ValueError as ex:
print(f"Couldn't cast the number. Description: {ex}")
return None
else:
task = Task(title, urgency)
return task
finally:
print(f"Done processing text: {text}")
A task-string processor converts urgency, handles ValueError, returns from either branch, and always prints a completion message from finally. section 12.4.2
A return in finally overrides an earlier return
In process_task_challenge("Laundry,3"), the try clause constructs a task and reaches return task. Before that return completes, finally runs and returns "finally" itself, so the function returns "finally" and skips the earlier return. section 12.4.4

