The website content provides an overview of six debugging techniques specifically tailored for Python programmers, ranging from basic print statements to using an Integrated Development Environment (IDE).
Abstract
The article "Six Debugging Techniques for Python Programmers" outlines essential strategies for troubleshooting code in Python. It begins with simple methods like printing variables to check their values and using assertions to validate assumptions. The article then introduces the Python logging module as a more professional approach to debugging, offering flexibility in outputting messages to various destinations like files or consoles. The fourth technique involves using the Python Debugger (pdb) for step-by-step code execution and inspection. The article also highlights the convenience of the breakpoint() function introduced in Python 3.7, which simplifies the process of setting breakpoints without the need for importing the pdb module. Additionally, the author emphasizes the benefits of using an Integrated Development Environment (IDE) for a more streamlined debugging experience. Lastly, the article acknowledges the timeless effectiveness of pen and paper for conceptualizing and solving complex problems. The conclusion encourages readers to share their own debugging techniques and invites them to explore further Python resources.
Opinions
The author suggests that while print statements are simple, they can clutter code and should be removed after debugging, unlike assert statements which can be toggled on or off.
The logging module is presented as a superior alternative to print and assert for debugging, providing a robust and flexible method for monitoring and recording program behavior.
The Python Debugger (pdb) is recommended for its ability to pause execution and inspect the program's state, which is particularly useful for large codebases.
The breakpoint() function is favored for its convenience and the flexibility it offers in switching between different debugging tools without altering the code.
The author expresses a preference for PyCharm as a Python IDE for its debugging capabilities.
The article underscores the sometimes overlooked effectiveness of traditional methods like using pen and paper to visualize and understand complex code structures and relationships.
Six Debugging Techniques for Python Programmers
Introduction
It’s nearly impossible that a program can be written once and run perfectly all the time. Bugs and debugging are part of the daily lives of programmers. Therefore, to learn some useful debugging techniques is an important task for every developer. This post will introduce six debugging techniques for Python developers.
1. Print and Check
The simplest but powerful method is to print some particular variables and check their values are as expected or not.
As the above example shown, if we are not sure with a variable, we can just print and check it. After that, some modifications can be considered.
The biggest disadvantage of using print is that you have to delete it in the future. The program will be hard to read if there are print statements everywhere and the results will also contain a lot of garbage information. No worries, we have other techniques.
2. Assert and Check
Wherever the print is used to assist debugging, assert can be used instead.
As the example shown, Python’s build-in assert method can raise an AssertionError if its statement is False .
Python gives us more flexibility when using assert. We can use the -0 parameter to close all the assert statements in the program when starting the Python interpreter. After that, all the assert methods will not work.
python -0 assert.py
# Traceback (most recent calllast):
# ...
# ValueError: invalid literal forint() with base 10: 'Yang'
Although the Assert and Check method is a little flexible than the Print and Check, lots of assert statements will also make our code a bit confusing and unreadable.
3. Using logging Module
Python has an important module named logging. Replacing print or assert to logging methods is more professional and powerful way to debug. Actually, it is a “heavy weapon” for a Python project. Because it gives us lots of flexibility and abilities to debug, record and monitor our programs.
For example, through simple configuration, a statement can be output to different places, such as console and files.
The above example shows that we can print logging messages to a file rather than console. It’s pretty useful if there is much information and inconvenient to look at them in the console. Not to mention it’s also helpful to look for logging history when they are saves in a file.
4. pdb
The fourth way is to start the Python debugger pdb, let the program run in a single step mode, and you can check the running status at any time. The pdb is a Python’s build-in debugger tool. There are some other debugger tools such as web-pdb, pudb and so on. In most cases, the pdb is useful enough.
A Basic Example
For example, we use pdb to run the following program step by step:
s = '0'n = int(s)print(1000 / n)
Firstly, we start the pdb in terminal:
$ python -m pdb test.py
Now our program are running from the first line:
> /home/yang/test.py(1)<module>()
-> s = '0'
We can check the full code using command l :
(Pdb) l1 -> s = '0'2n = int(s)3print(1000 / n)
Enter the command n to run next line of our code:
(Pdb) n
> /home/yang/test.py(2)<module>()
-> n = int(s)
(Pdb) n
> /home/yang/test.py(3)<module>()
->print(1000 / n)
(Pdb) n
ZeroDivisionError: division by zero
> /home/yang/test.py(3)<module>()
->print(1000 / n)
At any time, we can enter the command p and a variable name to check this value is correct or not:
(Pdb) p s
'0'
(Pdb) p n
0
Set Trace in Code
If there are lots of lines of our code, starting from the first line to use the pdb is very time consuming. We can use the function pdb.set_trace() to set a breakpoint in our code. For example:
import pdb
s = '0'
n = int(s)
pdb.set_trace()
# The program will be paused and start pdb debuggerprint(1000 / n)
Therefore, we can run the pdb from line the line of print(1000/n) .
A More Convenient Way
From Python 3.7, there is a build-in function breakpoint() which can totally replace the pdb.set_trace() .
s = '0'
n = int(s)
breakpoint()print(1000 / n)
The result is identical with the result of using pdb.set_trace() . Because breakpoint() calls sys.breakpointhook() function and this function calls pdb.set_trace() by default.
There are some benefits of using breakpoint() :
Obviously, using breakpoint() provides a little convenience because we don’t have to explicitly import pdb module.
More importantly, if we don’t like pdb and would like to use other debugger tools to replace it, there is no need to change our code.
For example, if we gonna use the web-pdb (or other debugger tools) which may be better than the pdb . The traditional method let us have to change every pdb.set_trace() statement to web_pdb.set_trace() (or other statement based on which tool are being used) in our code. Python should be elegant but this job is boring and not elegant at all.
Using breakpoint() , no need to change code. We just need to change the environment variable PYTHONBREAKPOINT at once.
$ PYTHONBREAKPOINT = web_pdb.set_trace python3.7
We can also set this variable to zero, then all the breakpoints will be ignored and our program will run normally rather than start the debugger tool.
$ PYTHONBREAKPOINT = 0 python3.7
5. Integrated Development Environment
If you want to set breakpoints and single-step execution more comfortably, you need an IDE (Integrated development environment) that supports debugging.
PyCharm: Great IDE designed for Python developers. By the way, this is my favourite Python IDE.
Eclipse plus the “pydev” plug-in can also debug Python programs.
… …
6. Pen and Paper
It sounds like a really traditional method but it can’t be ignored. Sometimes your mind is not very clear, writing it down with paper and pen is a good way to straighten out your thinking.
For example, I debugged a large project developed by others last year. There are lots of classes and complicated inheritance relationships between them. Unfortunately, there is no documents and even no code comments. In order to understand the relationships of classes, I wrote down the classes’ names and drew a draft diagram to help me sort their relationships out. After that, I found which one was wrong and caused the bug.
Conclusion
Debugging is programmers everyday life. We can use all different debugging tricks to make our life easier.
Please leave your comments if you have some interesting debugging tricks.
Thanks for reading. More Python related posts are here: