debugging
Objectives
- Explain common errors and how they occur in Python
- Use pdb to set breakpoints and step through code
- Use try and except blocks to handle errors
You're going to make mistakes...
So how do you fix them?
Understand
Them!
Let's start with some common errors!
SyntaxError
- Occurs when Python encounters incorrect syntax (something it doesn't parse).
- Usually due to typos or not knowing Python well enough
def first: # SyntaxError
None = 1 # SyntaxError
return # SyntaxError
NameError
This occurs when a variable is not defined, i.e. it hasn't been assigned
test
# NameError: name 'test' is not defined
TypeError
- An operation or function is applied to the wrong type
- Python cannot interpret an operation on two data types
len(5)
# TypeError: object of type 'int' has no len()
"awesome" + []
# TypeError: cannot concatenate 'str' and 'list' objects
Occurs when:
IndexError
Occurs when you try to access an element in a list using an invalid index (i.e. one that is outside the range of the list or string):
list = ["hello"]
list[2]
# IndexError: list index out of range
ValueError
This occurs when a built-in operation or function receives an argument that has the right type but an inappropriate value:
int("foo")
# ValueError: invalid literal for int() with base 10: 'foo'
KeyError
This occurs when a dictionary does not have a specific key:
d = {}
d["foo"]
# KeyError: 'foo'
AttributeError
This occurs when a variable does not have an attribute:
"awesome".foo
# AttributeError: 'str' object has no attribute 'foo'
Raise Your
Own Exception!
In python we can also throw errors using the raise keyword. This is helpful when creating your own kinds of exception and error messages.
raise ValueError('invalid value')
YOUR TURN
Handle Errors!
In Python, it is strongly encouraged to use try/except blocks, to catch exceptions when we can do something about them. Let's see what that looks like.
try:
foobar
except NameError as err:
print(err)
Why Not Catch Them All?
What we are doing here is catching every error, which means we are not able to correctly identify "what" went wrong. It is highly discouraged to do this.
try:
colt
except:
print("You tried to use a variable that was never declared!")
Any Better?
When you use try/except, make sure that a specific type of exception is being handled.
try:
colt
except NameError:
print("You tried to use a variable that was never declared!")
If you want to except a handful of exceptions, you can pass a tuple of errors into the except block as well:
try:
colt.hello
except (TypeError, AttributeError):
print("That doesn't work with this thing.")
Debugging with pdb
To set breakpoints in our code we can use pdb by inserting this line:
import pdb; pdb.set_trace()
import
This is how we include modules! We'll learn about these in quite a bit more depth later.
import pdb; pdb.set_trace()
For now, think of this as loading some external code and then running code right away
Using pdb
Inside of the debugger we can press c to continue and q to quit.
def add_then_multiply(num1, num2):
sum = num1 + num2
import pdb; pdb.set_trace()
product = sum * num1 * num2
return product
There are a few more shortcuts as well; you can read more about pdb here.
pdb Gotcha
Be careful with how you name your parameters!
def add_numbers(a, b, c, d):
import pdb; pdb.set_trace()
return a + b + c + d
Recap
- Python has many different types of errors
- You can use raise to throw your own errors
- using try and except is the best way to handle errors, just make sure you handle specific errors
- pdb is very useful for setting breakpoints and pausing execution of code
- certain characters have meaning in pdb so be careful with naming variables
YOUR TURN
Debugging
By colt
Debugging
- 4,722