Python Introduction to Exceptions
Table of Contents
In the last lesson, we learned about Python Iterating Through Dictionaries. Now let’s understand what happens when Python runs into an error.
Let’s Talk About Things Going Wrong
We write a program. We test it. It works. We feel good.
Then someone else uses it. And they do something we did not expect. They type a letter when we asked for a number. They try to divide by zero. They open a file that does not exist.
And our program crashes. It stops. It shows a big scary error message. And the user has no idea what happened.
That is what exceptions are about. They are errors that happen while the program is running. And Python gives us a way to handle them. So our program does not crash. It can deal with the problem and continue.
What Is an Exception in Python?
An exception is an error that occurs during the execution of a program.
It is not a syntax error. Syntax errors happen before the program runs. They are like typos. Python catches them when it reads our code.
Exceptions happen while the program is running. Something unexpected happens. Like dividing by zero. Or accessing a list index that does not exist. Or opening a file that is not there.
When an exception happens, Python stops the normal flow. It creates an exception object. And it looks for someone to handle it. If nobody handles it, the program crashes.
Common Exceptions in Python
Let’s look at a few common exceptions. We have probably seen some already.
ZeroDivisionError
This happens when we divide by zero.
print(10 / 0)Output
ZeroDivisionError: division by zeroValueError
This happens when we try to convert something that cannot be converted.
number = int("hello")Output
ValueError: invalid literal for int() with base 10: 'hello'TypeError
This happens when we use the wrong type.
print("Age: " + 25)Output
TypeError: can only concatenate str (not "int") to strIndexError
This happens when we use an index that does not exist.
numbers = [1, 2, 3]print(numbers[10])Output
IndexError: list index out of rangeKeyError
This happens when we use a dictionary key that does not exist.
person = {"name": "Alex"}print(person["age"])Output
KeyError: 'age'FileNotFoundError
This happens when we try to open a file that does not exist.
file = open("missing.txt", "r")Output
FileNotFoundError: [Errno 2] No such file or directory: 'missing.txt'There are many more. But these are the ones we will see most often.
What Happens When an Exception Is Not Handled?
If an exception happens and nobody handles it, the program stops. It prints a traceback. That is the long error message that shows where the error happened.
print("Start")print(10 / 0)print("End")Output
StartTraceback (most recent call last): File "example.py", line 2, in <module> print(10 / 0)ZeroDivisionError: division by zeroNotice that “End” is not printed. Because the program crashed at the division. It never reached the last line.
That is what happens without handling. The program just stops.
How to Handle Exceptions in Python
Python gives us a way to catch exceptions and handle them. So the program does not crash.
We use a try and except block.
try: print(10 / 0)except: print("Something went wrong")Output
Something went wrongThe code inside try is attempted. If an exception happens, Python jumps to the except block. It runs that code instead of crashing.
We will learn more about try and except in the next article. But that is the basic idea.
Python Exceptions: A Real-Life Example
Let’s say we are asking the user for a number. We want to divide 100 by that number.
number = int(input("Enter a number: "))result = 100 / numberprint(f"Result: {result}")If the user enters 0, we get a ZeroDivisionError. If they enter hello, we get a ValueError. The program crashes.
With exception handling, we can deal with it.
try: number = int(input("Enter a number: ")) result = 100 / number print(f"Result: {result}")except ValueError: print("That is not a valid number")except ZeroDivisionError: print("Cannot divide by zero")Now if the user enters 0, it says “Cannot divide by zero”. If they enter hello, it says “That is not a valid number”. No crash.
That is the power of exceptions.
Why Handle Exceptions in Python?
Three reasons.
First, it keeps our program running. Instead of crashing, it can deal with the problem and continue.
Second, it gives better error messages. Instead of a scary traceback, we can show the user a friendly message.
Third, it makes our code more robust. It can handle unexpected situations gracefully.
A Word of Caution
Let’s not overuse exceptions. They are for unexpected situations. Not for normal flow control.
For example, let’s not use exceptions to check if a key exists in a dictionary. We use in or get(). Exceptions should be for things that should not normally happen.
Common Mistakes with Python Exceptions
Mistake 1: Catching All Exceptions Blindly
try: # some codeexcept: passThis catches every exception and does nothing. That is bad. We might hide a real bug. It is better to catch specific exceptions.
Mistake 2: Not Handling Exceptions at All
number = int(input("Enter a number: "))If the user enters something wrong, the program crashes. Let’s always think about what could go wrong.
Mistake 3: Putting Too Much Code in try
try: # 50 lines of codeexcept: print("Error")This makes it hard to know what went wrong. Let’s keep the try block small. Only the code that might raise the exception.
Mistake 4: Using Exceptions for Normal Flow
try: value = my_dict["key"]except KeyError: value = "default"This works. But it is slower and less clear than using get().
value = my_dict.get("key", "default")Let’s use exceptions for exceptional cases.
Next, we will learn about Python try and except and handle errors without stopping the program.