Python try, except, and finally Statements
Learn how Python try, except, and finally statements handle exceptions and guarantee cleanup code runs after success or failure.
What are try, except, and finally?
An exception is a runtime error event that interrupts normal execution unless it is handled. Python's try, except, and finally clauses let you control what happens when an operation may fail.
- try block: The suite of code containing operations that may raise an exception.
- except block: The suite that handles an exception raised while Python executes the associated
tryblock. - finally clause: A clause whose suite runs after the
trystatement's processing, whether the attempt succeeds or a handled exception occurs.
A cleanup action is a required finishing action, such as closing a file or releasing a connection. A termination clause is another descriptive name for finally when it performs closing or shutdown work.
For related exception basics, see Python try and except statements and Python error types.
Basic try, except, and finally syntax
The clauses must appear in this order: try, one or more optional except clauses, and an optional finally clause. Each clause has an indented body. Python uses indentation to determine which statements belong to each block.
try:
# Code that may raise an exception
operation()
except:
# Code that handles an exception
print("Something went wrong")
finally:
# Code that should run after the attempt
print("Attempt finished")The bare except: form is a general catch-all pattern for introductory examples. In production code, catching a specific exception, such as ValueError, usually makes the program safer and easier to understand.
try:
number = int("not a number")
except ValueError:
print("The conversion failed")
finally:
print("Conversion attempt finished")How finally executes
Python executes the try suite first. If it completes normally, no applicable except body runs, and Python then executes finally. If the try suite raises an exception handled by an except clause, Python executes that handler and then executes finally.
This makes finally appropriate for an action that must occur regardless of the outcome. In ordinary Python control flow, the finally suite also runs before an exception continues propagating when no matching handler exists.
try:
print("The operation succeeded")
except ValueError:
print("The operation failed")
finally:
print("Always perform this finishing step")With this example, the try message is printed, the except message is skipped, and the finally message is printed. If the operation instead raised a handled ValueError, the exception message would be printed before the finally message.
Try statement clause behavior
| Try block result | except block runs | else block runs | finally block runs |
|---|---|---|---|
| Try completes normally | No | Yes, if an else clause exists | Yes |
Try raises an exception handled by except | Yes | No | Yes |
finally compared with else
An else clause and a finally clause have different purposes:
elseruns only when thetrysuite completes without an exception.finallyruns after the attempt whether thetrysuite succeeds or a matchingexcepthandler handles an exception.
try:
result = calculate_value()
except ValueError:
print("Could not calculate a value")
else:
print("Use result only after successful calculation")
finally:
print("Release resources or finish the task")Put normal-success-only code in else. For example, processing result may make sense only when calculation succeeded. Put unavoidable completion or cleanup work in finally.
For a comparison focused on else, see Python try, except, and else statements.
Input conversion example
input() returns text. The expression int(input(...)) attempts to convert that text to an integer. If the user enters text that is not a valid integer, int() raises ValueError. A ValueError commonly means that a value has the right general type but an unsuitable value for the requested operation.
print("Starting age input")
try:
age = int(input("Enter your age: "))
print("Age recorded:", age)
except ValueError:
print("Invalid input: enter a whole number.")
finally:
print("Age input attempt complete.")Successful input path
Suppose the user enters 55. The prompt appears, int() converts the text to the integer 55, and the success message is printed. Because no exception occurred, the except body is skipped. The finally message still appears.
Starting age input
Enter your age: 55
Age recorded: 55
Age input attempt complete.Failed input path
Suppose the user enters a. The conversion raises ValueError, so Python skips the remaining statements in the try suite and runs the matching except body. After that, it runs finally.
Starting age input
Enter your age: a
Invalid input: enter a whole number.
Age input attempt complete.Age input outcomes
| User input | Conversion result | except output | finally output |
|---|---|---|---|
55 | Converted successfully to integer 55 | None | Age input attempt complete. |
a | Raises ValueError | Invalid input: enter a whole number. | Age input attempt complete. |
Cleanup use case: closing a file
File processing may fail after a file has been opened. A finally block can close the file so that the cleanup occurs even when later processing raises an exception.
file = None
try:
file = open("report.txt", "r")
contents = file.read()
print(contents)
except OSError:
print("The file could not be opened or read")
finally:
if file is not None:
file.close()
print("File cleanup complete")Initializing file to None lets the finally block check whether opening succeeded before calling close(). Modern Python programs often use a context manager with the with statement for file cleanup, but finally explains the underlying cleanup principle. See how to read and write files for file operations.
Termination use case: ending a session
A session-ending action belongs in finally when it must happen after a task, whether the task succeeds or fails.
session = start_session()
try:
perform_task(session)
except RuntimeError:
print("The task failed")
finally:
end_session(session)
print("Session ended")The call to end_session(session) is a termination action. It prevents the normal success path from being the only place where the session is closed.
Reading the execution order
- Python enters the
tryblock. - Python evaluates each statement until the block finishes or an exception occurs.
- If a matching exception occurs, Python runs the applicable
exceptblock. If there is no exception, it skips allexceptblocks. - If an
elseclause exists, Python runs it only after an exception-freetryblock. - Python runs the
finallyblock after the preceding processing.
When reading output, look for the prompt first, then any success or exception-handling output, and finally the cleanup or completion message. A successful conversion skips exception output but does not skip finalization. A failed conversion produces both the applicable except output and the finally output.
Common problems
Letters entered where an integer is expected
Problem: A user enters letters when the program expects an integer.
Cause: int() cannot convert the supplied text into an integer.
Solution: Catch ValueError and use finally for the message or cleanup that must still occur.
Expecting finally to run only after an error
Cause: finally is being confused with exception-only handling.
Solution: Run the age example once with 55 and once with a. The except body runs only in the failing run, while the finally body runs in both.
Putting success-only code in finally
Cause: The roles of else and finally have been mixed up.
Solution: Use else for work that requires successful completion of the try block. Use finally for cleanup, shutdown, or another unavoidable finishing action.
Indentation or syntax errors
The except and finally clauses must align with try, while each clause body must be indented consistently.
try:
value = int(input("Number: "))
except ValueError:
print("Invalid number")
finally:
print("Finished")Do not indent except or finally inside the try body, and do not place finally before the exception-handling clauses.
Key points
- Put risky operations in a
tryblock. - Use
exceptto handle an appropriate exception from that block. - Use
elsefor code that should run only after success. - Use
finallyfor cleanup or termination code that should run after either success or handled failure. - For conversion failures from
int(),ValueErroris the usual specific exception to catch. - Correct clause order and indentation are required.
Next, practice catching specific exceptions and learn about nesting exception handling statements.