Introduction
PySnooper is a library that helps in debugging the Python code. The normal approach as of today with Python is to use various print statements for debugging and identifying the issues in Python or using various breakpoints/watches with a full-fledged debugger. PySnooper is very convenient to use and with just one decorator it displays what’s going on with our code. The article explains how to install and how to use PySnooper with some example code. Let’s explore.
Installation
As with any other Python library, installation steps are the same, using “pip install” / “conda install -c conda-forge pysnooper”.
Example
Using PySnooper debugger is very straightforward, all we need is to import pysnooper library and using a decorator “@pysnooper.snoop()” line to the function we will see the entire log of the function which includes the line ran when the line is executed and how and when variables are getting changed, cool isn’t it. This level of granularity is seldom achieved. Let’s use a simple example which is printing the elements of a list in a loop,
import pysnooper
@pysnooper.snoop()
def printList(nums):
for i in nums:
print(i)
nums = [10,20,30,40]
print(printList(nums))
Along with printing the elements, the entire function is tracked by PySnooper, the debugger is giving us information like at what time, the line number executed, the value of the variable and if variable is modified or not. PySnooper also allows us to debug the portion of the code, not necessarily the entire function. Let's understand by another example that has 2 loops. All we need to do is, to remove the decorator ‘“@pysnooper.snoop()’ from the function and wrap the relevant part of the code where debugging is required with a 'with' block, "with pysnooper.snoop()".
import pysnooper
def printList(nums1, nums2):
for i in nums1:
print(i)
with pysnooper.snoop():
for j in nums2:
print(j)
The only relevant part is debugged for us using the ‘with’ block.
Redirecting Logs to a file
The code blocks that we have seen are simple. In reality, we have to deal and write more complex code and we may need to redirect the logs to a separate file, that option is available with PySnooper. We need to specify the file location and name within the decorator and a new file if not exists will be created and logs will be redirected.
import pysnooper
@pysnooper.snoop("logs.txt")
def printList(nums):
for i in nums:
print(i)
nums = [10,20,30,40]
print(printList(nums))
PySnooper will create a file logs.txt in the current directory and logs will not be printed on the console anymore, it will be redirected to a “logs.txt” file.
PySnooper with Other Python Libs
Let’s take a slightly more complex program, the program will read pandas files and chain them to find the result.
import pysnooper
import pandas as pd
@pysnooper.snoop()
def sortedByLikesInDescendingOrder(dataframe):
return df.sort_values(by='likes', ascending=False)
@pysnooper.snoop()
def filterMoreThanMillionLikes(dataframe):
return dataframe[dataframe['likes'] > 1000000]
@pysnooper.snoop()
def filterByTitle(dataframe):
return dataframe[dataframe.title.str.startswith('BTS')]
@pysnooper.snoop()
def read_file():
df = pd.read_csv('USvideos.csv')
df_final = (df.pipe(sortedByLikesInDescendingOrder)
.pipe(filterMoreThanMillionLikes)
.pipe(filterByTitle))
df_final.head()
Other attributes
The debug statements contain lots of machine data. If we don’t want them, we can simply use normalize=True with a decorator (@pysnooper.snoop(normalize=True)) and the irrelevant info is removed.
In a multi-threaded application for identifying which threads are snooped, we can use @pysnooper.snoop(thread_info=True)
Showcasing snoop lines for functions that your function calls using @pysnooper.snoop(depth=2)
Summary
In the article we have seen, how to install and how to use PySnooper in a Python program as well as we have seen using PySnooper with other libraries as well like Pandas. It’s convenient to use PySnooper and it’s strongly recommended to use it.