The debugging process using print statements can get very tedious especially when you don’t really know where the issue might be. Also running the same script multiple times with lots of print statements after each slight change in the code can be time consuming.
The disadvantages with print debugging:
- Lots of print statements that only output info about script state for the current run
- Lack of knowledge about the state of the whole script
- Inability to alter the script for a quick test in the same run
Wouldn't it be nice to make the debugging experience more interactive?
TLDR
Debugging python scripts using python interactive console.
Start you python script in interactive mode: python -i my_script.py
Use python built in code
module to drop inside interactive console from you python code:
code.interact(
banner='Start interactive mode',
local=locals(),
exitmsg='Exiting interactive mode')
Interactive mode
You can run your python scripts in interactive mode using the -i
parameter in the command line.
# example_sript.py
class Person:
def __init__(self, age):
self.age = age
age_list = [19, 4, 55, 14]
person_list = [Person(age=age) for age in age_list]
def display_age_rating():
for person in person_list:
if person.age < 18:
print(f"The content is rated 'M' for mature and can not be shown to a {person.age} year old.")
else:
print(f"Being {person.age} year you fall under the mature age group.")
Now run it from inside of your console:
python -i example_sript.py
>>>
From here you get all the advantages of using python interactive console.
- Checkout the values of your local variables:
>>> age_list
[19, 4, 55, 14]
- Invoke functions:
>>> display_age_rating()
Being 19 year you fall under the mature age group.
The content is rated 'M' for mature and can not be shown to a 4 year old.
Being 55 year you fall under the mature age group.
The content is rated 'M' for mature and can not be shown to a 14 year old.
- Change your program state for quick testing:
>>> age_list = [100]*4
>>> age_list
[100, 100, 100, 100]
>>> person_list = [Person(age=age) for age in age_list]
>>> display_age_rating()
Being 100 year you fall under the mature age group.
Being 100 year you fall under the mature age group.
Being 100 year you fall under the mature age group.
Being 100 year you fall under the mature age group.
Use Ctrl+D
or type in exit()
and press enter to quit the interactive python console.
This method makes debugging experience much more flexible compared to print debugging. But what if you need to debug not a single script but a whole application with multiple files?
Dropping inside interactive mode from inside the code
The built in code
python module will allow us to drop inside interactive mode from anywhere in our code during the script execution. To do that we need to invoke interact()
function in our script.
# Import code module
import code
class Person:
def __init__(self, age):
self.age = age
age_list = [19, 4, 55, 14]
person_list = [Person(age=age) for age in age_list]
def display_age_rating():
for age in age_list:
if age < 18:
print(f"The content is rated 'M' for mature and can not be shown to a {age} year old.")
else:
print(f"Being {age} year you fall under the mature age group.")
code.interact(
banner='Start interactive mode before invoking display_age_rating',
local=locals(),
exitmsg='Exiting interactive mode')
display_age_rating()
interact()
creates an InteractiveConsole
instance. This pauses the execution of the script and starts the read-eval-print loop. It takes in four parameters:
-
banner
accepts a string which will be displayed at the start of the interactive mode instance -
local
sets a default namespace for the interpreter loop -
readfunc
can be used as the InteractiveConsole.raw_input() method if provided -
exitmsg
accepts a string which will be displayed after exiting interactive mode instance
💡 For the
local
parameter we can manually provide a dictionary of local or global variables that we can access inside interactive mode instance
local={’age_list’: age_list}
Now we can start our small program and use the interactive console the same way as if we provided the -i
parameter mentioned previously.
python3 interactive_mode.py
Start interactive mode before invoking display_age_rating
>>> age_list
[19, 4, 55, 14]
>>> display_age_rating()
Being 19 year you fall under the mature age group.
The content is rated 'M' for mature and can not be shown to a 4 year old.
Being 55 year you fall under the mature age group.
The content is rated 'M' for mature and can not be shown to a 14 year old.
>>>
By pressing Ctrl+D
we exit current interactive session and let our program finish executing
>>>
Exiting interactive mode
Being 19 year you fall under the mature age group.
The content is rated 'M' for mature and can not be shown to a 4 year old.
Being 55 year you fall under the mature age group.
The content is rated 'M' for mature and can not be shown to a 14 year old.
We are able to enter interactive console from different parts of our code by placing the interact()
function where needed.
import code
age_list = [19, 4, 55, 14]
def display_age_rating():
for age in age_list:
code.interact(
banner='age_list loop iteration',
local=locals(),
exitmsg='Exiting interactive mode')
if age < 18:
print(f"The content is rated 'M' for mature and can not be shown to a {age} year old.")
else:
print(f"Being {age} year you fall under the mature age group.")
code.interact(
banner='Start interactive mode before invoking display_age_rating',
local=locals(),
exitmsg='Exiting interactive mode')
display_age_rating()
That way we are able to jump to the next point of our scripts execution by pressing Ctrl+D
.
python3 interactive_mode.py
Start interactive mode before invoking display_age_rating
>>> age_list
[19, 4, 55, 14]
>>>
Exiting interactive mode
age_list loop iteration
>>> person.age
19
>>> person.age = 100
>>> person.age
100
>>>
Exiting interactive mode
Being 100 year you fall under the mature age group.
age_list loop iteration
>>> person.age
4
>>>
Exiting interactive mode
The content is rated 'M' for mature and can not be shown to a 4 year old.
age_list loop iteration
>>>...
To quit the interactive mode use exit()
.
Conclusion
Python interactive console safes time debugging our code by letting us check the code state and change it on the fly. The code module provides a more flexible way to interact with our code and better understand it’s behavior. For more info check our the official documentation of the code module.
Hopefully this post was helpful. I’d like to now what tools and approaches do you use for debugging your python code. Feel free to comment down below.
Top comments (0)