使用Python中PDB模块中的命令来调试Python代码的教程

作者:Ashley 时间:2021-04-28 21:22:57 

你有多少次陷入不得不更改别人代码的境地?如果你是一个开发团队的一员,那么你遇到上述境地的次数比你想要的还要多。然而,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
0
投稿

猜你喜欢

  • 关于Python错误重试方法总结

    2023-05-10 23:42:09
  • 一小时学会TensorFlow2之全连接层

    2022-11-27 10:35:30
  • 谈谈网页设计中的字体应用 (1) Font Set

    2009-11-24 12:55:00
  • pytest框架之fixture详细使用详解

    2022-01-22 01:47:19
  • django中瀑布流写法实例代码

    2022-08-04 11:11:26
  • 一个将半角"转换为中文"的asp函数

    2007-09-19 11:47:00
  • PHP扩展Swoole实现实时异步任务队列示例

    2023-11-10 05:11:22
  • JS获取checkbox的个数简单实例

    2023-08-20 15:17:55
  • asp如何实现对Session 数组的定义和调用?

    2010-05-18 18:40:00
  • 在Python中使用SQLite的简单教程

    2022-05-12 04:01:46
  • Softmax函数原理及Python实现过程解析

    2022-12-15 02:18:24
  • Python+Opencv实战之人脸追踪详解

    2022-09-22 16:03:38
  • 仿dw8代码折叠功能的HTML编辑器

    2008-04-29 21:19:00
  • python数据挖掘使用Evidently创建机器学习模型仪表板

    2022-10-23 14:21:52
  • 解决python中使用plot画图,图不显示的问题

    2021-09-27 16:00:07
  • python中关于range()函数反向遍历的几种表达

    2023-07-09 20:23:33
  • Python Pandas 删除列操作

    2023-12-17 22:03:53
  • python读写LMDB文件的方法

    2021-12-17 15:12:37
  • 实例讲解如何利用crontab定时备份MySQL

    2009-01-04 13:06:00
  • Javascript"篱式"条件判断(翻译)

    2008-08-01 12:21:00
  • asp之家 网络编程 m.aspxhome.com