Table of Contents
Why `try` and `except`?
Sometimes your code will hit a problem while it is running — for example:
- Dividing by zero
- Converting text to a number when the text isn’t numeric
- Opening a file that doesn’t exist
These are runtime errors (exceptions). Without handling them, your program stops and shows a traceback. With try and except, you can catch these errors and decide what to do instead of crashing.
try/except is not for hiding all problems. It’s for handling expected or possible errors gracefully.
Basic `try` / `except` Structure
The simplest pattern:
try:
# code that might cause an error
x = int("hello") # this will raise an error
except:
# what to do if an error happens
print("Something went wrong")Flow:
- Python runs the code inside the
tryblock. - If no error occurs:
exceptis skipped. - If an error occurs: Python jumps to the
exceptblock.
This “bare” except (without specifying an error type) works, but you usually want to be more specific.
Handling Specific Exception Types
Different errors have different exception types, such as:
ValueError— for bad values (likeint("hello"))ZeroDivisionError— for division by zeroFileNotFoundError— when a file is missing
You can catch a specific type:
try:
number = int(input("Enter a whole number: "))
result = 10 / number
print("Result is:", result)
except ValueError:
print("That was not a valid whole number.")
except ZeroDivisionError:
print("You cannot divide by zero.")Now:
- If converting to
intfails →ValueError→ firstexceptruns. - If the user enters
0→ZeroDivisionError→ secondexceptruns. - Other kinds of errors still crash, which is good: it means you see unexpected bugs.
You can also catch multiple related exceptions in one except:
try:
value = int(input("Enter a number: "))
except (ValueError, TypeError):
print("That input could not be converted to an integer.")Getting Information About the Error
You can give the exception a name and inspect it:
try:
num = int(input("Number: "))
except ValueError as e:
print("Conversion failed:", e)Here:
eis an object that holds details about what went wrong.- Printing
eshows the system’s message, for example:invalid literal for int() with base 10: 'abc'.
This is useful for logging or debugging, even if you also give a friendly message to the user.
Using `else` with `try` / `except`
You can add an else block that runs only if no exception happened:
try:
age = int(input("Enter your age: "))
except ValueError:
print("Please enter a valid number for your age.")
else:
print("Next year you will be", age + 1)Order:
tryruns.- If an exception happens →
exceptruns →elseis skipped. - If no exception →
exceptis skipped →elseruns.
This is handy for keeping the “normal success path” separate from the “error path.”
Using `finally` for Cleanup
finally is code that always runs, whether an error occurs or not. It’s commonly used for cleanup actions (like closing files or network connections):
file = None
try:
file = open("data.txt", "r")
content = file.read()
print("File content:", content)
except FileNotFoundError:
print("The file 'data.txt' was not found.")
finally:
if file is not None:
file.close()
print("File closed.")Execution rules:
tryruns.- If an exception matches an
except, thatexceptruns. - Then the
finallyblock always runs. - Even if you
returnfrom insidetryorexcept,finallystill runs before the function really exits.
In many modern cases, you can also use context managers (e.g., with open(...)) to handle this, but finally is important to understand.
Nested `try` / `except`
You can put a try/except inside another, but it can quickly get confusing. Use it when you want to handle different risky parts separately.
Example:
try:
filename = input("Enter filename: ")
try:
f = open(filename, "r")
except FileNotFoundError:
print("File not found.")
else:
print("File opened successfully.")
f.close()
except KeyboardInterrupt:
print("\nInput cancelled by user.")Here:
- Inner
tryis about opening the file. - Outer
tryis about the input possibly being interrupted.
For beginners, it’s usually better to keep nesting shallow and code clear.
Common Patterns with `try` / `except`
1. Retrying Until Valid Input
Instead of letting invalid input crash the program, ask again:
while True:
try:
number = int(input("Enter a whole number: "))
break # exit the loop if conversion works
except ValueError:
print("That is not a whole number. Please try again.")
print("You entered:", number)
Here, try/except is used to control flow based on whether an error happens.
2. Optional Files or Settings
If something is optional, you might ignore one specific error but still let others show:
try:
config_file = open("config.txt", "r")
config = config_file.read()
config_file.close()
except FileNotFoundError:
print("No config file found. Using default settings.")This “ask for forgiveness, not permission” style is common in Python: you just try the risky operation and handle the specific error if it happens.
3. Converting Safely with a Default
You might want to convert a string to a number and fall back to a default on error:
user_input = input("Enter a price: ")
try:
price = float(user_input)
except ValueError:
print("Invalid price, using 0.0 instead.")
price = 0.0
print("Final price:", price)What *Not* to Do with `try` / `except`
1. Do Not Hide Every Error
Avoid a bare except that swallows everything:
try:
risky_code()
except:
pass # Very bad: silently ignore all errorsThis can make bugs invisible and very hard to find. At minimum, print or log something, and preferably catch specific exceptions:
try:
risky_code()
except SomeSpecificError as e:
print("Handled expected problem:", e)2. Do Not Use `try` / `except` Instead of Thinking
try/except is not a replacement for planning or checking values when appropriate. Use it to handle unexpected situations or problems you cannot fully prevent, not to avoid writing proper checks where they make sense.
Combining `try`, `except`, `else`, and `finally`
All four parts together:
try:
num = int(input("Enter a number: "))
result = 10 / num
except ValueError:
print("You must enter a valid number.")
except ZeroDivisionError:
print("The number cannot be zero.")
else:
print("10 divided by your number is:", result)
finally:
print("Thank you for using this program.")Behavior:
- If input isn’t a number →
ValueErrorblock runs, thenfinally. - If input is
0→ZeroDivisionErrorblock runs, thenfinally. - If input is valid and nonzero →
elseruns, thenfinally.
Practice Ideas
Try writing small snippets that:
- Ask for a filename, read it, and:
- Show the content if it exists.
- Print a friendly message if it doesn’t (
FileNotFoundError). - Ask for two numbers and divide them, handling:
- Non-numeric input (
ValueError). - Division by zero (
ZeroDivisionError). - Use a
whileloop withtry/exceptto keep asking for a positive number, and only proceed once the user gives a valid one.
While practicing, pay attention to:
- Which line might raise which exception.
- Which
exceptwill catch it. - Whether the
elseandfinallyblocks run in each case.
This will make try and except feel natural when you start writing larger programs.