Each kind of failure has its own exception type. Catching the right one tells the reader exactly what you expected to fail.
int("hello") # ValueError: invalid literal for int() with base 10: 'hello'
d["missing"] # KeyError: 'missing'
open("nope") # FileNotFoundError: [Errno 2] No such file or directory: 'nope'Each one a different name, each one descriptive.
And often you want to handle them differently. "Bad input" might mean prompt the user again; "file not found" might mean fall back to defaults. Same try block, two except clauses:
try:
text = open(path).read()
n = int(text)
except FileNotFoundError:
n = 0 # default
except ValueError:
print("file content isn't a number")
n = 0Or one except with a tuple of types?
Yes — if the handling is the same:
except (FileNotFoundError, ValueError):
n = 0Use separate except blocks when the response is different. Use the tuple form when the response is the same.
And today we convert a list of strings to ints, skipping the ones that fail.
Right. int("42") works, int("oops") raises ValueError. Catch the ValueError, print "skip", continue with the rest.
| Exception | When it fires |
|---|---|
KeyError | d["missing"] on a dict |
IndexError | lst[100] past the end of a list |
ValueError | int("hello"), float("abc") — wrong shape input to a parser |
TypeError | "a" + 1 — wrong types combined |
FileNotFoundError | open("missing.txt") |
ZeroDivisionError | n / 0 |
AttributeError | value.method_that_doesnt_exist() |
All inherit from a base Exception class, but you'll almost always catch a specific one.
except blocksDifferent handling per type:
try:
do_work()
except FileNotFoundError:
print("file missing")
except PermissionError:
print("can't read it")
except ValueError:
print("bad content")Python tries each except in order; first match wins.
except, tuple of typesSame handling for several types:
try:
do_work()
except (FileNotFoundError, PermissionError):
print("can't access")except order matters with inheritanceIf you catch a parent class before a child, the child is unreachable:
try:
open("x").read()
except Exception: # catches FileNotFoundError too
handle_generally()
except FileNotFoundError: # never runs — Exception caught it first
handle_specifically()List the most specific first.
A classic shape: you have a list of inputs, some are bad, you want to process the good ones and report the bad ones.
for s in ["10", "oops", "20"]:
try:
n = int(s)
print(n)
except ValueError:
print("skip")
# 10
# skip
# 20The try is inside the loop body so each iteration starts fresh — one bad item doesn't kill the loop.
Each kind of failure has its own exception type. Catching the right one tells the reader exactly what you expected to fail.
int("hello") # ValueError: invalid literal for int() with base 10: 'hello'
d["missing"] # KeyError: 'missing'
open("nope") # FileNotFoundError: [Errno 2] No such file or directory: 'nope'Each one a different name, each one descriptive.
And often you want to handle them differently. "Bad input" might mean prompt the user again; "file not found" might mean fall back to defaults. Same try block, two except clauses:
try:
text = open(path).read()
n = int(text)
except FileNotFoundError:
n = 0 # default
except ValueError:
print("file content isn't a number")
n = 0Or one except with a tuple of types?
Yes — if the handling is the same:
except (FileNotFoundError, ValueError):
n = 0Use separate except blocks when the response is different. Use the tuple form when the response is the same.
And today we convert a list of strings to ints, skipping the ones that fail.
Right. int("42") works, int("oops") raises ValueError. Catch the ValueError, print "skip", continue with the rest.
| Exception | When it fires |
|---|---|
KeyError | d["missing"] on a dict |
IndexError | lst[100] past the end of a list |
ValueError | int("hello"), float("abc") — wrong shape input to a parser |
TypeError | "a" + 1 — wrong types combined |
FileNotFoundError | open("missing.txt") |
ZeroDivisionError | n / 0 |
AttributeError | value.method_that_doesnt_exist() |
All inherit from a base Exception class, but you'll almost always catch a specific one.
except blocksDifferent handling per type:
try:
do_work()
except FileNotFoundError:
print("file missing")
except PermissionError:
print("can't read it")
except ValueError:
print("bad content")Python tries each except in order; first match wins.
except, tuple of typesSame handling for several types:
try:
do_work()
except (FileNotFoundError, PermissionError):
print("can't access")except order matters with inheritanceIf you catch a parent class before a child, the child is unreachable:
try:
open("x").read()
except Exception: # catches FileNotFoundError too
handle_generally()
except FileNotFoundError: # never runs — Exception caught it first
handle_specifically()List the most specific first.
A classic shape: you have a list of inputs, some are bad, you want to process the good ones and report the bad ones.
for s in ["10", "oops", "20"]:
try:
n = int(s)
print(n)
except ValueError:
print("skip")
# 10
# skip
# 20The try is inside the loop body so each iteration starts fresh — one bad item doesn't kill the loop.
Create a free account to get started. Paid plans unlock all tracks.