Different kinds of errors
Each kind of error has its own exception, and its name tells what went wrong. Here are the ones you'll meet most often, in the Python interpreter:
>>> int("3.5")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '3.5'
>>> "Age: " + 30
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
>>> [1, 2, 3][5]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> {"a": 1}["b"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'b'
>>> 10 / 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero- ValueError: a value of the right type, but with contents that don't work.
int("3.5")gets a string, as it should, but not one that's a whole number;float("twelve")fails the same way. - TypeError: a value of the wrong type for what the code does with it, such as adding a number to a string, or repeating a string by a string,
"ab" * "3". - IndexError: an index that a list or a string doesn't have.
- KeyError: a key that a dictionary doesn't have.
- ZeroDivisionError: dividing by zero, with
/,//or%. The zero usually comes from data: a number the user typed, or one read from a file. - FileNotFoundError: opening a file that doesn't exist. (Its cousin PermissionError comes when the file is there but the program may not use it, such as a file that belongs to another user of the computer.)
Several except blocks
One try can have several except blocks, one for each kind of error it is ready for. Python checks them in order and runs the first one that matches. Only one of them runs:
colors = ["red", "green", "blue"]
try:
index = int(input("Which color (0-2)? "))
print("You picked", colors[index])
except ValueError:
print("That's not a number.")
except IndexError:
print("There's no color with that number.")
5Which color (0-2)? 5
There's no color with that number.A missing file is handled the same way. Print a message of your own that says what happened:
try:
with open("settings.txt") as file:
print(file.read())
except FileNotFoundError:
print("No settings.txt, using the default settings.")
No settings.txt, using the default settings.A bare except hides mistakes
except: without a name catches every exception there is. That's tempting, but it can't tell the user's mistakes from the program's own. This program has a bug: the days are numbered from 1, but list indexes start at 0, so it should look up days[number - 1]:
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
try:
number = int(input("Day number (1-7): "))
print("That's", days[number])
except:
print("Please type a number from 1 to 7.")
7Day number (1-7): 7
Please type a number from 1 to 7.The user did type a number from 1 to 7. days[7] raised an IndexError, and the bare except turned the program's bug into a message that blames the user. Name the exception you expect from the user instead, here ValueError, and the bug shows itself:
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
try:
number = int(input("Day number (1-7): "))
print("That's", days[number])
except ValueError:
print("Please type a number from 1 to 7.")
7Day number (1-7): 7Traceback (most recent call last):
File "main.py", line 4, in <module>
print("That's", days[number])
~~~~^^^^^^^^
IndexError: list index out of rangeThe traceback names the line with the wrong index. So catch only the exceptions you expect, and let real bugs show their traceback.