Interview frequency: …
Short answer
except handles the matching exception, else runs only when the try block succeeds without an exception, and finally always runs whether the operation succeeded or failed.
Explanation
Put only the code you expect to fail inside try and move what follows to else; that way you do not accidentally catch an exception from the success path thinking it came from the original operation. finally suits cleanup such as closing files and releasing locks, although a context manager (with) is often clearer. Avoid return inside finally because it swallows the exception in flight, and Python 3.14 emits a warning for it (PEP 765).
Code example
try:
value = int(text)
except ValueError:
value = None
else:
audit(value) # Does not execute if conversion fails
finally:
release_lock() # Always executesCommon mistakes
- Putting a large block of code inside try, so it catches exceptions you did not intend.
- Using return inside finally, which hides the original exception.
Follow-up questions
- When do you need ExceptionGroup and except*?
- How do you choose the right exception and deal with the exception hierarchy?