Using PySnooper for Python Debugging
When your Python code doesn’t run as expected or when you want to examine if your program is running correctly, you may use a full-fledged debugger with breakpoints and watches. But in some cases, you can’t be bothered to set one up right now.
You want to know which lines are running and which aren’t, and what the values of the local variables are.
Most people would use print lines, in strategic locations, some of them showing the values of variables.
PySnooper lets you do the same, except instead of carefully crafting the right print lines, you just add one decorator line to the function you’re interested in. You’ll get a play-by-play log of your function, including which lines ran and when, and exactly when local variables were changed.
Installation
Install PySnooper using pip
pip install pysnooper
Using conda
conda install -c conda-forge pysnooper
Usage
Here is an example how PySnooper works. Let say you have a function to sum up to the n
. Let’s snoop on it by adding the @pysnooper.snoop()
decorator:
import pysnooper
@pysnooper.snoop()
def sum_up(number):
s = 0
for i in range(1, number+1):
s += i
return s
print(sum_up(10))
The output to the console is:
Starting var:.. number = 5
14:52:25.242890 call 5 def sum_up(number):
14:52:25.243049 line 6 s = 0
New var:....... s = 0
14:52:25.244005 line 7 for i in range(1, number + 1):
New var:....... i = 1
14:52:25.244005 line 8 s += i
Modified var:.. s = 1
14:52:25.244983 line 7 for i in range(1, number + 1):
Modified var:.. i = 2
14:52:25.244983 line 8 s += i
Modified var:.. s = 3
14:52:25.251813 line 7 for i in range(1, number + 1):
Modified var:.. i = 3
14:52:25.254806 line 8 s += i
Modified var:.. s = 6
14:52:25.272309 line 7 for i in range(1, number + 1):
Modified var:.. i = 4
14:52:25.275238 line 8 s += i
Modified var:.. s = 10
14:52:25.278208 line 7 for i in range(1, number + 1):
Modified var:.. i = 5
14:52:25.280118 line 8 s += i
Modified var:.. s = 15
14:52:25.281806 line 7 for i in range(1, number + 1):
14:52:25.282758 line 10 return s
14:52:25.284699 return 10 return s
Return value:.. 15
15
Or if you don’t want to trace an entire function, you can wrap the relevant part in a with block:
import pysnooper
def average(number):
s = 0
for i in range(1, number + 1):
s += i
with pysnooper.snoop():
avg = s / number
return avg
print(average(5))
The output:
New var:....... number = 5
New var:....... s = 15
New var:....... i = 5
14:57:20.398242 line 10 avg = s / number
New var:....... avg = 3.0
14:57:20.410059 line 12 return avg
3.0
Features
You can redirect the output to a file:
@pysnooper.snoop('/path/to/output/file.log')
Add prefix to snoop lines
@pysnooper.snoop(prefix='DEBUG ')
Conclusion
Using PySnooper for debugging makes it easier than using multiple print
statements. It shows more detail, and of course, it saves your time adding print
statement. But if you are using IDE with debugger with breakpoints and watches, use it instead.