Python 调试器 (pdb)
在软件开发术语中,“调试”一词通常用于指定位并纠正程序中错误的过程。Python 的标准库包含 pdb 模块,它是一组用于调试 Python 程序的实用程序。
调试功能在 Pdb 类中定义。该模块在内部使用 bdb 和 cmd 模块。
pdb 模块具有非常方便的命令行界面。它在 Python 脚本执行时使用 –m 开关导入。
python –m pdb script.py
为了进一步了解调试器的工作原理,让我们首先编写一个 Python 模块 (fact.py) 如下所示:
def fact(x): f = 1 for i in range(1,x+1): print (i) f = f * i return f if __name__=="__main__": print ("factorial of 3=",fact(3))
从命令行开始调试此模块。在这种情况下,代码执行会在第一行停止,并在其左侧显示箭头 (->),并生成调试器提示符 (Pdb)。
C:\python36>python -m pdb fact.py > c:\python36\fact.py(1)<module>() -> def fact(x): (Pdb)
要查看所有调试器命令的列表,请在调试器提示符前键入“help”。要了解有关任何命令的更多信息,请使用“help <command>”语法。
list 命令列出整个代码,并在程序已停止的行左侧使用 -> 符号。
(Pdb) list 1 -> def fact(x): 2 f = 1 3 for i in range(1,x+1): 4 print (i) 5 f = f * i 6 return f 7 if __name__=="__main__": 8 print ("factorial of 3 = ", fact(3))
要逐行遍历程序,请使用 step 或 next 命令。
(Pdb) step > c:\python36\fact.py(7)<module>() -> if __name__=="__main__": (Pdb) next > c:\python36\fact.py(8)<module>() -> print ("factorial of 3 = ", fact(3)) (Pdb) next 1 2 3 factorial of 3= 6 --Return-- > c:\python36\fact.py(8)<module>()->None -> print ("factorial of 3 = ", fact(3))
step 和 next 命令之间的主要区别在于,step 命令会导致程序在函数内停止,而 next 命令则执行被调用的函数并在其之后停止。
C:\python36>python -m pdb fact.py > c:\python36\fact.py(1)<module>() -> def fact(x): (Pdb) s > c:\python36\fact.py(7)<module>() -> if __name__=="__main__": (Pdb) n > c:\python36\fact.py(8)<module>() -> print ("factorial of 3=",fact(3)) (Pdb) s --Call-- > c:\python36\fact.py(1)fact() -> def fact(x): (Pdb) n > c:\python36\fact.py(2)fact() -> f = 1 (Pdb) n > c:\python36\fact.py(3)fact() -> for i in range(1,x+1): (Pdb) n > c:\python36\fact.py(4)fact() -> print (i) (Pdb) n 1 > c:\python36\fact.py(5)fact() -> f = f * i (Pdb) n > c:\python36\fact.py(3)fact() -> for i in range(1, x + 1): (Pdb) n > c:\python36\fact.py(4)fact() -> print (i) (Pdb) f,i (1, 2) (Pdb)
step 命令还在程序遇到函数调用时显示 --call-- 指示,并在函数结束时显示 --return---。在任何时候,我们都可以通过只输入变量名来检查某个变量的值。
您可以使用 break 命令在程序中设置断点。必须给出行号(应在其中设置断点)。例如,“break 5”将在当前程序的第 5 行设置断点。
(Pdb) list 2 f = 1 3 for i in range(1, x + 1): 4 print (i) 5 f = f * i 6 return f 7 -> if __name__=="__main__": 8 print ("factorial of 3=",fact(3)) [EOF] (Pdb) break 5 Breakpoint 1 at c:\python36\fact.py:5 (Pdb) continue 1 > c:\python36\fact.py(5)fact() -> f = f * i (Pdb) break Num Type Disp Enb Where 1 breakpoint keep yes at c:\python36\fact.py:5 breakpoint already hit 1 time (Pdb) continue 2 > c:\python36\fact.py(5)fact() -> f = f * i (Pdb) b Num Type Disp Enb Where 1 breakpoint keep yes at c:\python36\fact.py:5 breakpoint already hit 2 times
发出“continue”命令后,程序执行将继续进行,直到遇到断点。要显示所有断点,只需发出不带行号的 break 命令。
任何断点都可以通过 disable/enable 命令禁用/启用,或通过 clear 命令完全清除。
(Pdb) disable 1 Disabled breakpoint 1 at c:\python36\fact.py:5 (Pdb) b Num Type Disp Enb Where 1 breakpoint keep no at c:\python36\fact.py:5 breakpoint already hit 2 times
Pdb 调试器也可以从 Python 脚本内部使用。为此,在脚本顶部导入 pdb,并在程序内使用 set_trace() 方法。
import pdb def fact(x): f = 1 for i in range(1,x+1): pdb.set_trace() print (i) f = f * i return f if __name__=="__main__": print ("factorial of 3=",fact(3))
调试器的行为将与我们在命令行环境中找到的完全相同。