What Python does when something goes wrong, the errors you will meet most often, and how to raise your own.
# ValueError - invalid value
try:
int("abc")
except ValueError:
print("Cannot convert to int")
Right type (a string), but a value int() cannot convert.
# TypeError - wrong type
try:
"2" + 2
except TypeError:
print("Type mismatch")
A string and an int cannot be added.
# KeyError - missing key
try:
d = {"a": 1}
value = d["b"]
except KeyError:
print("Key not found")
# IndexError - invalid index
try:
lst = [1, 2, 3]
value = lst[10]
except IndexError:
print("Index out of range")
# AttributeError - no attribute
try:
x = 5
x.append(1)
except AttributeError:
print("Attribute not found")
An int has no append method.
# FileNotFoundError
try:
with open("missing.txt") as f:
pass
except FileNotFoundError:
print("File not found")
# PermissionError
try:
with open("/root/file.txt", "w") as f:
pass
except PermissionError:
print("Permission denied")
The file does not exist, or it exists but you are not allowed to open it that way.
# raise an exception
def validate_age(age):
if age < 0:
raise ValueError("Age cannot be negative")
return age
raise stops the function immediately; nothing after it runs.
def validate_age(age):
if age < 0:
raise ValueError(
"Age cannot be negative")
return age
def register(age):
return validate_age(age)
try:
register(-5)
except ValueError as e:
print("Rejected:", e)
call withNo matching except in a function? It is abandoned and the exception moves on to its caller.
# re-raise same exception
try:
result = 10 / 0
except ZeroDivisionError:
print("Logging error...")
raise
A bare raise inside except sends the same exception on up, after you have logged it.
Which exception, if any?
# ValueError when?
int("3.14")
# ans: ValueError
# TypeError example?
len(5)
# ans: TypeError (int has no len)
# KeyError vs get?
d = {"a": 1}
d["b"]
# ans: KeyError
d.get("b")
# ans: None
# IndexError negative?
lst = [1, 2]
lst[-10]
# ans: IndexError
# NameError?
print(undefined_variable)
# ans: NameError
# ZeroDivisionError?
5 / 0
# ans: ZeroDivisionError
5 // 0
# ans: ZeroDivisionError
# raise with message?
raise ValueError("Custom message")
# ans: raises with message
# raise without exception?
try:
raise
except:
pass
# ans: RuntimeError (no active exception)
A bare raise needs an exception being handled; here there is none, so Python raises RuntimeError, which the bare except then swallows.
# exception hierarchy?
try:
x = 1 / 0
except Exception:
print("Caught")
# ans: catches ZeroDivisionError
# assert raises what?
assert False, "Message"
# ans: AssertionError: Message
ValueError bad value, TypeError wrong type, KeyError missing key, IndexError bad position, AttributeError no such attribute, NameError unknown name.
An exception leaves each function until some try has a matching except; if none does, the program stops with a traceback.
raiseRaise your own with a message; a bare raise in an except re-raises the current one.
except ExceptionCatches almost everything, because most exceptions inherit from Exception.