你有多少次陷入不得不更改别人代码的境地?如果你是一个开发团队的一员,那么你遇到上述境地的次数比你想要的还要多。然而,Python中有一个整洁的调试特性(像其他大多数语言一样),在这种情况下使用非常方便。本文是一篇快速教程,希望它能让你的编码生活更加容易。
1. 一个混乱的程序
出于本教程的目的,让我们研究一下下面的简单程序。
这个程序接收两个命令行参数,然后执行加法和减法操作。
(假设用户输入的是有效值,因此代码中我们没有进行错误处理。)
import sys def add(num1=0, num2=0): return int(num1) + int(num2) def sub(num1=0, num2=0): return int(num1) - int(num2) def main(): #Assuming our inputs are valid numbers print sys.argv addition = add(sys.argv[1], sys.argv[2]) print addition subtraction = sub(sys.argv[1], sys.argv[2]) print subtraction if __name__ == '__main__': main()
2. PDB
Python提供了一个有用的模块PDB,它实际上是一个交互式源代码调试器。
你需要下面的两行代码来使用此模块。
import pdb pdb.set_trace()
看一下我们修改过的程序,里面包含了一些断点。
import pdb import sys def add(num1=0, num2=0): return int(num1) + int(num2) def sub(num1=0, num2=0): return int(num1) - int(num2) def main(): #Assuming our inputs are valid numbers print sys.argv pdb.set_trace() # <-- Break point added here addition = add(sys.argv[1], sys.argv[2]) print addition subtraction = sub(sys.argv[1], sys.argv[2]) print subtraction if __name__ == '__main__': main()
3. 程序执行触发调试器
一旦你设置好断点以后,你就可以像平时一样执行程序。
python debugger.py 1 2
程序将会在遇到的第一个断点处停止执行。
['debugger.py'] > /Users/someuser/debugger.py(15)main() -> addition = add(sys.argv[1], sys.argv[2]) (Pdb)
我们在第14行设置了一个断点,所以我们能看到将要执行的下一行是第15行。可以看到,在执行到第15行之前程序已经停止。
在这里我们有几个选项,让我们在下面步骤中看看一些调试指令。
4. 下一行->n
在你的调试器提示中,输入n运行到下一行。
> /Users/someuser/debugger.py(14)main() -> addition = add(sys.argv[1], sys.argv[2]) (Pdb) n > /Users/someuser/debugger.py(15)main() -> print addition
这会执行当前行代码,并准备执行下一行。
我们可以使用n来逐行执行整个程序,但这其实没有什么用处。
可能你已经看到,PDB实际上并没有进入我们的add函数中。下面,就让我们看看其他几个令调试更加有趣的选项。
注意:
一个更酷的特性是你可以单击回车键来执行以前的命令(在本例中只要指令n)。
5. 打印->p
下面,我们再次开始调试程序。(你可以通过单击c使PDB跳到末尾或者直到下一个断点,因为程序中我们并没有其他的断点了,所有程序将会执行完成。)
['debugger.py', '1', '2'] > /Users/someuser/debugger.py(14)main() -> addition = add(sys.argv[1], sys.argv[2]) (Pdb)
现在,如果我们想知道sys.argv中包含什么内容,我们可以输入以下内容:
-> addition = add(sys.argv[1], sys.argv[2]) (Pdb) p sys.argv ['debugger.py', '1', '2'] (Pdb) p sys.argv[1] '1' (Pdb)
使用这种方法可以相当方便地查看变量中实际存储着什么值。
现在我们将进入加法函数内部。
6. 单步->s
我们可以使用“s”进入加法函数内部。
(Pdb) s --Call-- > /Users/someuser/debugger.py(4)add() -> def add(num1=0, num2=0): (Pdb) n > /Users/someuser/debugger.py(5)add() -> return int(num1) + int(num2) (Pdb)
这将把我们带入加法函数的内部,现在我们可以在加法函数内部使用n、p和其他的操作指令。
此时单击“r”将会把我们带到前面进入函数的返回语句。
如果你想快速跳转到一个函数的结尾处,那么这个指令将很有用。
7. 动态添加断点- > b
前面,在程序运行之前,我们使用pdb.set_trace()设置了一个断点。
不过,经常在调试会话已经开始之后,我们想要在程序中特定的地方添加断点。
这里我们就可以使用选项“b”来实现这种目的。
我们重新开始执行程序。
['debugger.py', '1', '2'] > /Users/someuser/debugger.py(15)main() -> addition = add(sys.argv[1], sys.argv[2]) (Pdb)
此时我在第18行设置一个断点。
-> addition = add(sys.argv[1], sys.argv[2]) (Pdb) b 18 Breakpoint 1 at /Users/someuser/debugger.py:18 (Pdb) c We are in add-- 3 > /Users/someuser/debugger.py(18)main() -> print subtraction (Pdb) p subtraction -1 (Pdb)
从上面我们可以看到,PDB跳到了第18行并等待下一个指令。
同时,PDB还为该断点分配了一个号码(在本例中是1)。为了以后的执行,我们可以通过开启或禁用断点号码来启用或停用对应的断点。
8. 列表->l
有时在调试的时候,你可能会忘记此时你处在代码的什么地方。在这种情况下,使用“l”将会打印出一个友好的总结,它能够显示出此刻你在代码中的位置。
['debugger.py', '1', '2'] > /Users/someuser/debugger.py(15)main() -> addition = add(sys.argv[1], sys.argv[2]) (Pdb) l 10 11 def main(): 12 #Assuming our inputs are valid numbers 13 print sys.argv 14 pdb.set_trace() # <-- Break point added here 15 -> addition = add(sys.argv[1], sys.argv[2]) 16 print addition 17 subtraction = sub(sys.argv[1], sys.argv[2]) 18 print subtraction
9. 动态分配变量
在调试会话期间,你可以分配变量来帮助你进行调试,知道这些对你来说也是有帮助的。例如:
['debugger.py', '1', '2'] > /Users/someuser/debugger.py(15)main() -> addition = add(sys.argv[1], sys.argv[2]) (Pdb) n We are in add-- > /Users/someuser/debugger.py(16)main() -> print addition (Pdb) p addition 3 #<--- addition here is 3 (Pdb) addition = 'this is now string' #<--- We changed the value of additon (Pdb) n this is now string #<--- Now when we print it we actually gets it as a string. that we just set above. > /Users/someuser/debugger.py(17)main() -> subtraction = sub(sys.argv[1], sys.argv[2])
注意:
如果你想设置一些如n(即PDB指令)这样的变量,你应该使用这种指令:
(Pdb) !n=5 (Pdb) p n 5
10. 结束->q
最后,在代码的任何地方如果你想结束调试,可以使用“q”,那么正在执行的程序将会终止。
11. 扩展阅读
本文只涉及到了PDB的表面用法,其实使用PDB你还可以做到更多(PDB 文档)。
使用IPython的人可以在ipdb中找到一个更好的调试器,它提供了tab补充、语法高亮和其他一些很酷的特性。
本文向大家介绍Python使用pdb调试代码的技巧,包括了Python使用pdb调试代码的技巧的使用技巧和注意事项,需要的朋友参考一下 什么是pdb 不知道大家在用Python写代码出现报错时是怎样调试的,从报错提示定位回去一步一步check每一行?如果没有IDE或者命令行写代码时又该怎样快速调试?这时如果使用pdb进行调试将会异常方便。 Pdb就是Python debugger,是python自
本文向大家介绍python的pdb调试命令的命令整理及实例,包括了python的pdb调试命令的命令整理及实例的使用技巧和注意事项,需要的朋友参考一下 python的pdb调试命令的命令整理及实例 一、命令整理 pdb调试命令 完整命令 简写命令 描述 args a 打印当前函数的参数 break b 设置断点 clear cl 清除断点 condition 无 设置条件断点 continue c
本文向大家介绍python中pdb模块实例用法,包括了python中pdb模块实例用法的使用技巧和注意事项,需要的朋友参考一下 大家可能都不大熟悉关于pdb这个模块,实际上就是python中的内置模块,主要作用于命令行调试代码,下面我们将通过是哪个小结给大家详细介绍下使用该内容的方式,首先是简单介绍,然后为大家呈现实例,最后就是总结啦,小伙伴是不是相当期待呢,那就板正做好,一起来详细了解下吧~ 简
问题内容: 我知道可以从命令行使用以下命令调试Python脚本 如果是打算与一起运行的脚本。 但是,python模块应与一起运行。即使包含相对导入的脚本也应使用来运行。如何在的控制下运行?以下 无效 : 问题答案: 您现在无法执行此操作,因为会终止选项列表 这意味着 mod的 工作是解释其余的参数列表,而这种行为完全取决于 mod 在内部的设计方式以及它是否支持另一个 -m 让我们看看里面有什么发
本文向大家介绍在Python中使用模块的教程,包括了在Python中使用模块的教程的使用技巧和注意事项,需要的朋友参考一下 Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用。 我们以内建的sys模块为例,编写一个hello的模块: 第1行和第2行是标准注释,第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身
本文向大家介绍总结用Pdb库调试Python的方式及常用的命令,包括了总结用Pdb库调试Python的方式及常用的命令的使用技巧和注意事项,需要的朋友参考一下 用Pdb调试有多种方式 使用 Pdb调试 Python的程序的方式主要是下面的三种!下面逐一介绍 命令行加-m参数 命令行启动目标程序,加上-m参数,这样调用 testPdb.py的话断点就是程序执行的第一行之前 本文接下来重点讲到的实例展