Using try, except, else, and finally in Python
Learn how Python exception handling blocks work together so you can catch errors, run code only when no error happens, and always clean up resources.
Quick example
try:
number = int(input("Enter a number: "))
except ValueError:
print("Please enter a valid whole number.")
else:
print("You entered:", number)
finally:
print("Program finished.")
Use try for risky code, except for handling specific errors, else for success-only code, and finally for cleanup code that must always run.
What this page covers
- Explain the purpose of
try,except,else, andfinally - Show the order these blocks run
- Help beginners choose the right block for each task
- Focus on practical exception handling patterns
What try does
Put code that might fail inside a try block.
Python watches this block for exceptions. An exception is an error that happens while the program is running.
If an error happens inside try:
- Python stops running the rest of that
tryblock - Python looks for a matching
exceptblock - If it finds one, that handler runs
Example:
try:
result = 10 / 0
print("This line will not run.")
except ZeroDivisionError:
print("You cannot divide by zero.")
Output:
You cannot divide by zero.
Here, 10 / 0 raises a ZeroDivisionError, so Python skips the print() inside try.
If you are new to exceptions, see Python errors and exceptions explained.
What except does
except handles an error that happened in try.
You should catch specific exceptions when possible. This makes your code easier to understand and debug.
Common exception types include:
ValueErrorZeroDivisionErrorFileNotFoundError
Example:
try:
age = int("hello")
except ValueError:
print("That value cannot be converted to an integer.")
Output:
That value cannot be converted to an integer.
Try to avoid a bare except like this:
try:
age = int("hello")
except:
print("Something went wrong.")
This catches almost everything, which can hide useful error details.
A better version is:
try:
age = int("hello")
except ValueError:
print("Please enter a valid number.")
If you want more practice with this pattern, see how to use try except blocks in Python.
What else does
else runs only if the try block succeeds.
That means:
- no exception happened in
try - Python did not jump to
except
Use else for code that should run only after the risky code worked.
Example:
try:
number = int("42")
except ValueError:
print("Invalid number")
else:
print("Conversion worked:", number)
Output:
Conversion worked: 42
Why is this useful?
- It keeps the
tryblock small - It makes debugging easier
- It clearly separates risky code from success code
Do not use else to handle errors. That is what except is for.
What finally does
finally runs whether an error happens or not.
Use it for cleanup work, such as:
- closing files
- releasing resources
- printing a final message
- resetting temporary state
Example:
try:
print("Trying something")
except ValueError:
print("A value error happened")
finally:
print("This always runs")
Output:
Trying something
This always runs
In normal Python execution, finally still runs even if there is a return statement in try or except in many cases.
Example:
def test():
try:
return "from try"
finally:
print("Cleaning up")
print(test())
Output:
Cleaning up
from try
Execution order of the blocks
Python always starts with try.
If no exception happens
The order is:
tryelsefinally
Example:
try:
print("Try block")
except ValueError:
print("Except block")
else:
print("Else block")
finally:
print("Finally block")
Output:
Try block
Else block
Finally block
If a matching exception happens
The order is:
tryexceptfinally
Example:
try:
number = int("abc")
except ValueError:
print("Except block")
else:
print("Else block")
finally:
print("Finally block")
Output:
Except block
Finally block
If the exception is not caught
If no matching except block handles the error, finally still runs before the program stops with the error.
try:
print(10 / 0)
except ValueError:
print("Wrong type of exception")
finally:
print("Finally still runs")
Output:
Finally still runs
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
When to use each block
Use each block for one clear purpose:
try: risky codeexcept: what to do if it failselse: code to run only on successfinally: cleanup that must always happen
A good mental model is:
- Try it
- Handle failure
- Continue on success
- Clean up at the end
Beginner example with user input
This example converts user input to an integer.
int()may failValueErroris caught if the input is not a valid whole numberelseruns only when conversion succeedsfinallyalways prints the final message
try:
number = int(input("Enter a whole number: "))
except ValueError:
print("Please enter a valid whole number.")
else:
print("You entered:", number)
finally:
print("Program finished.")
Possible output if the user enters 25:
Enter a whole number: 25
You entered: 25
Program finished.
Possible output if the user enters hello:
Enter a whole number: hello
Please enter a valid whole number.
Program finished.
If you keep seeing this kind of problem, see ValueError in Python: causes and fixes.
Example with file handling
This example tries to open and read a file.
open()may fail if the file does not existexcept FileNotFoundErrorhandles that caseelseruns only when the file was opened successfullyfinallycloses the file if it was opened
file = None
try:
file = open("message.txt", "r")
content = file.read()
except FileNotFoundError:
print("The file was not found.")
else:
print("File content:")
print(content)
finally:
if file is not None:
file.close()
print("File closed.")
Why do we set file = None first?
Because if open() fails, the file variable would not be created inside try. Setting it before the try block makes it safe to check in finally.
If you are working with file errors, see FileNotFoundError in Python: causes and fixes.
Best practices
- Catch the most specific exception you can
- Keep the
tryblock as small as possible - Do not hide errors silently
- Use
finallyfor cleanup, not normal program logic - Use
elseto separate success code from risky code
Good example:
try:
number = int(user_input)
except ValueError:
print("Invalid input")
else:
print("Valid number:", number)
This is better than putting everything inside try, because it is clearer which line might fail.
You can learn more patterns in how to handle exceptions in Python.
Common beginner mistakes
Putting too much code inside try
Bad:
try:
number = int(user_input)
print("Number entered")
total = number * 10
print("Total:", total)
except ValueError:
print("Invalid input")
Better:
try:
number = int(user_input)
except ValueError:
print("Invalid input")
else:
print("Number entered")
total = number * 10
print("Total:", total)
This makes it clearer that only the conversion is risky.
Using except without naming an exception type
This can catch unexpected errors and make debugging harder.
Prefer:
except ValueError:
instead of:
except:
Confusing else with except
Remember:
exceptruns when an error happenselseruns when no error happens
Using finally when cleanup is not needed
You do not have to use finally every time. Use it when something must always happen at the end.
Catching errors but not fixing the real cause
This is not very helpful:
try:
number = int(text)
except ValueError:
pass
It hides the problem.
At minimum, print a useful message or handle the input another way.
Common causes of confusion
These are common reasons beginners struggle with exception blocks:
- Using
tryaround a large block of unrelated code - Catching
Exceptionor using bareexcepttoo early in learning - Putting code that can also fail inside
exceptwithout another plan - Trying to use a variable in
finallythat was never created intry - Forgetting that
elseruns only when no exception occurs
Useful debugging commands
These commands can help when you are learning exception handling:
python your_script.py
print(type(value))
print(repr(value))
help(ValueError)
help(FileNotFoundError)
These are useful because:
python your_script.pyruns your program from the terminaltype()shows what kind of value you haverepr()shows a more exact version of a valuehelp()shows built-in documentation for an exception type
FAQ
Do I need to use all four blocks every time?
No. You can use only the blocks you need. Many programs use just try and except.
What is the difference between except and else?
except runs when an error happens. else runs when no error happens.
Does finally always run?
In normal Python execution, yes. It is meant for cleanup code that should always run.
Should I use bare except?
Usually no. It can hide useful error details and make debugging harder.
Can I have more than one except block?
Yes. You can catch different exception types with separate except blocks.
Example:
try:
value = int(input("Enter a number: "))
result = 10 / value
except ValueError:
print("That was not a valid integer.")
except ZeroDivisionError:
print("You cannot divide by zero.")
else:
print("Result:", result)
finally:
print("Done.")