python调试工具pdb简介
The Python Debugger (pdb) is a powerful tool that all Python developers should be familiar with. It is an interactive debugger that you can start up anywhere in your codebase. This makes debugging complex or confusing code much simpler, since you can interact directly with the code in a running state.Basic CommandsThere are just a few basic pdb commands you need to know in order to start being productive. If you want more info, you can always look at the internal help:
(Pdb) help(Pdb) help listThe most basic commands you will need are list, next, step and continue. This will allow you to do basic navigation of the debugging session so you can figure out what is happening in the code.
listShow the lines in the file you are currently debugging. Very helpful if you've drilled down further into the codebase and are unfamiliar with the code.nextExecute the next line in the file. This allows you to go line by line and inspect the state of the code at that point.stepDig deeper into the code that is being called on that line. If it is a function, it will take you into that function so you can inspect the state from there.continueExit out of the debugger but still execute the code. When you do this, it will be like you never stopped the execution of the program in the first place.Invoking pdbThe easiest way to invoke pdb is to add a set_trace in your code. Here is an example:
import pdb; pdb.set_trace()This is a PEP8 violation, but you should never check this code in, so we won't worry about that.
Another way is to invoke the pdb module from the command line.
$ python -m pdb mycode.pyChoose the method that works best for your situation. We will use the command line method to see how pdb works in the next section.
Example Debug SessionHere is an example of a debugging session with pdb:$ python -m pdb example.py
> example.py(1)<module>() -> my_string = 'one' (Pdb) next 1 -> my_string = 'one' 2 my_other_string = 2 3 4 print my_string + my_other_string > example.py(2)<module>() -> my_other_string = 2 (Pdb) next (Pdb) next 1 my_string = 'one' 2 my_other_string = 2 3 4 -> print my_string + my_other_string TypeError: "cannot concatenate 'str' and 'int' objects"
Now we are stopped at the line that has the error on it and can inspect the current state of things further.
> example.py(4)<module>() -> print my_string + my_other_string (Pdb) type(my_string) <type 'str'> (Pdb) type(my_other_string) <type 'int'> (Pdb) my_other_string 2
Now what if I try some alternatives?
(Pdb) print my_string + '2'
one2
(Pdb) print my_string + str(my_other_string)
one2
(Pdb) print '{}{}'.format(my_string, my_other_string)
one2
This gives you a chance to find out what will actually work when you are in this situation. Then you can go modify your code, run your tests and get that bug fixed!
Alternative pdb implementationsThere are a few different implementations out there that build upon pdb. These replacements typically enhance the experience by adding things like tab completion and syntax highlighting. My favorite is pdb++ because it has a sticky_by_default option that shows the whole context of the code as you step through it, eliminating the need to use the list command in most cases.
Another alternative is ipdb, which embeds an IPython interpreter as the pdb prompt. If you've ever used IPython, then you know how powerful it can be. Now you can have that power in the debugger.
One main difference between these two alternatives is that ipdb uses a separate import to do a set_trace in the code. Whereas pdb++ overrides the standard set_trace to invoke itself. This makes dropping in pdb++ into your project a seamless operation.
Helpful Links
- I gave a talk entitled So You Think You Can PDB? at PyOhio 2014, which goes over the basic usage in more detail.
- Nathan Yergler gave an excellent talk at PyCon 2014, going over a lot more features of pdb and the recent changes in Python 3. Watch In Depth PDB to learn more.