Chapter 13: Handling the Unexpected - Errors and Exceptions
As you write more complex programs, you'll inevitably encounter errors. This is a completely normal part of programming! Sometimes these are simple syntax errors that Python points out before the program even runs. But other times, errors happen while the program is running, causing it to stop and crash. These are called exceptions.
For example, what happens if your program tries to:
Read a file that doesn't exist? (
FileNotFoundError)Divide a number by zero? (
ZeroDivisionError)Convert a word like "hello" into an integer? (
ValueError)
In these cases, Python "raises an exception" and halts. In this chapter, you'll learn how to anticipate and manage these exceptions gracefully, preventing your programs from crashing and making them more robust and user-friendly.
The Problem: An Unhandled Exception
Let's look at a simple program that can easily crash.
# calculator.py
age_str = input("What is your age? ")
age = int(age_str) # This line can cause a ValueError
result = 100 / age # This line can cause a ZeroDivisionError
print(f"100 divided by your age is: {result}")
If you run this and enter a number like 25, it works perfectly. But if you enter zero or 0, you get a crash with a wall of red text ending in ZeroDivisionError. If you enter ten, you get a ValueError. This red text is called a traceback, and it's Python's way of telling you what went wrong and where.
A traceback is helpful for you, the developer, but it's a confusing and abrupt end for a user. We can do better.
The Solution: The try...except Block
try...except BlockTo handle potential exceptions, you can place your "risky" code inside a try block. If an error occurs in that block, the code inside the corresponding except block is executed, and the program doesn't crash.
Here's the structure:
Let's make our calculator safer.
Now, if you enter ten or 0, the program prints our friendly error message and continues on instead of crashing.
Being Specific: Handling Different Exceptions
The except block in the example above is a bit too general—it catches every possible error. It's better practice to be specific about the exceptions you expect to handle. This way, you don't accidentally hide bugs you weren't aware of.
You can specify the type of exception you want to "catch".
Now our program gives a more specific, helpful message depending on what went wrong.
The else and finally Blocks
else and finally BlocksThere are two more optional parts of a try...except statement that give you even more control.
The else Block
else BlockThe code in the else block runs only if the try block completes successfully (i.e., no exceptions were raised). This is useful for code that depends on the try block succeeding.
The finally Block
finally BlockThe code in the finally block runs no matter what. It will execute whether the try block succeeded, failed with an exception, or even if you exit the program from within the try block. It's often used for cleanup actions, like closing a file.
Summary and What's Next
You've learned how to make your programs much more resilient.
An exception is an error that happens during program execution.
The
tryblock contains code that might raise an exception.The
exceptblock contains the code to handle that exception. It's best to catch specific exceptions likeValueErrororFileNotFoundError.The
elseblock runs only if no exception occurred.The
finallyblock runs no matter what.
This is a key concept in writing professional, high-quality code. Now that you can handle data, files, and errors, you're ready to learn about a powerful new way to structure your programs. In the next chapter, we'll introduce the foundational concepts of Object-Oriented Programming (OOP), which will change the way you think about writing code.
Practice Time!
Take the
guest_book.pyprogram from the last chapter. It already usestry...except FileNotFoundError. Add afinallyblock that prints "Guest book interaction complete."Write a program that has a list of numbers
[1, 5, 0, 8]. Loop through the list and for each numbern, try to print the result of10 / n. Usetry...except ZeroDivisionErrorto handle the case wherenis 0.
Last updated