Rocket's crew counter asks how many crew are aboard. A visitor types four, in letters, and the whole program stops with a ValueError.
"I cannot stop people from typing words," Rocket says. "But I do not want the program to crash every time they do."
Raven thinks about how she would handle it in person. "What do you notice?" she asks. "If someone gave me a word instead of a number, I would just ask again, politely."
Nova shows a path that splits in two and joins back together. "Would you like a hint?" she asks. "Python can try something risky. If a certain error happens, it runs a different block instead of stopping."
Rocket writes try, and then except ValueError.
Python runs the try block. If a ValueError happens inside it, Python jumps to the except ValueError block instead of stopping. If no error happens, the except block is skipped.
Name the error you expect. Catching every possible error hides real bugs, so programmers keep the except as narrow as they can.
# ask_number.py
def ask_number(question):
"""Keep asking until the user types a whole number."""
while True:
text = input(question)
try:
return int(text)
except ValueError:
print("Please type a whole number, like 12.")
crew = ask_number("How many crew aboard? ")
print("Crew aboard:", crew) How many crew aboard? four Please type a whole number, like 12. How many crew aboard? 4.5 Please type a whole number, like 12. How many crew aboard? 4 Crew aboard: 4
Last week you checked os.path.exists before loading a file. A try and except can do the same job: try to open it, and catch FileNotFoundError.
# load_or_start.py
import json
def load_list(filename):
"""Load a JSON list, or start an empty one."""
try:
with open(filename) as f:
return json.load(f)
except FileNotFoundError:
return []
items = load_list("not_made_yet.json")
print("Loaded", len(items), "items") Any error you expect can be caught. Here, sharing supplies among zero crew would divide by zero, so the function catches that case and returns 0.
# per_person.py
def per_person(supplies, crew):
"""Whole supplies each crew member gets."""
try:
return supplies // crew
except ZeroDivisionError:
return 0
print(per_person(20, 4))
print(per_person(20, 3))
print(per_person(20, 0)) 5 6 0
| Statement | True or false? |
|---|---|
| If no error happens, the except block is skipped. | ? |
| except ValueError also catches a ZeroDivisionError. | ? |
| A narrow except helps real bugs stay visible. | ? |
| try and except can replace every test you write. | ? |
Your programs can now recover from mistakes instead of stopping. Tomorrow you will write tests that check your functions automatically.