Python pdb 教程 - Python pdb

2024年8月29日 | 阅读 7 分钟

在本教程中,我们将学习 Python 的调试工具 pdb。调试应用程序是在开发者时间紧迫且希望其正常工作时令人不快的活动。我们将介绍使用 pdb(Python 的交互式源代码调试器)的基础知识。我们还将介绍 pdb 的一些常用用法。

跟踪 bug 并更快速可靠地修复有缺陷的代码是一种很好的做法。让我们来介绍一下 Python pdb 模块。

Python pdb 模块

Python pdb 模块用于在 Python 中进行调试,它内置于 Python 标准库中。pdb 被定义为 Pdb 类,该类在内部利用 bdb(基本调试器函数)和 cmd(支持面向行的命令解释器)模块。

它具有在命令行上运行的优点,非常适合在远程服务器上调试代码。

pdb 模块支持设置断点、单步执行代码、查看堆栈跟踪和源代码列表。

启动 Python 调试器

Python 提供了多种调用调试器的方法。

我们需要插入 import pdb, pdb.set_trace() 命令来在程序内开始调试。如果我们定义了程序中的断点,我们的脚本就会自动在该断点处停止执行。Python 提供了 breakpoint() 函数,它的作用与我们手动定义的作用相同。让我们理解下面的例子。

示例 - 1:两个数字相加

故意出错 - input() 函数返回字符串,程序会将这些字符串连接起来,而不是相加输入的数字。

输出

> d:\python project\test_pdb.py(8)()
-> x = input("Enter first number : ")
(Pdb) &
*** SyntaxError: invalid syntax

解释 -

在上面的输出中,第一行是可执行文件的目录路径,断点所在行的行号,以及 <module>.。这意味着我们在 test_pdd.py 文件的第 8 行设置了一个断点,它出现在 <> 内部。下一行表示我们执行停止的代码行。该行尚未执行。然后我们有一个 pdb 提示符,可以使用以下命令进行代码导航。

命令函数
help它用于显示所有命令。
其中它用于显示当前行的堆栈跟踪和行号。
next它执行当前行并移至下一行,忽略函数调用。
step它会单步进入当前行调用的函数。

例如,当我们在 pdb 提示符下运行 help 命令时,它会显示 -

现在我们可以检查变量 whatis 的类型和变量名。让我们看下面的例子。

示例 -

当我们使用 next 命令时 -

打印表达式

print 命令会计算传入的表达式。如果传递一个变量名,pdb 会打印其当前值。但是,我们可以执行几项操作来确定正在运行的应用程序的状态。

让我们来理解下面的例子。我们使用 get_path() 方法获取文件路径。为了检查程序进程,我们调用 pdb.set_trace() 来暂停执行。

示例 -

输出

> d:\python project\test_pdb.py(891)get_path()
-> return head
(Pdb)

那么上面代码中发生了什么 -

  • 我们在函数 get_path() 的第 8 行有一个文件 test_pdb.py。这是 p 命令将用于解析变量名的参考帧,即当前上下文的范围。
  • 我们的程序已在 get_path() 函数的第 8 行的 return head 处停止,如上面一行所示。

现在让我们打印一些表达式来获取应用程序的当前状态。

我们可以将有效的求值表达式传递给 p 命令。

当我们在调试程序并想直接使用测试替代实现时,这些表达式非常有帮助。也可以使用 pp(pretty-print)命令。当我们要打印输出量很大的变量时,它很有用。

事后调试

事后调试是指在程序完成执行过程后进入调试模式。pdb 模块提供了 pm()post_morterm() 函数。这些函数直接指向导致错误的行。让我们来理解下面的例子 -

示例 -

输出

Enter first number : 34
Enter second number : 65
Traceback (most recent call last):
  File "d:/Python Project/test_pdb.py", line 9, in 
    result = mul(x, y)
  File "d:/Python Project/test_pdb.py", line 3, in mul
    answer = a * b
TypeError: can't multiply sequence by non-int of type 'str'

检查变量栈

程序使用的所有局部或全局变量都维护在堆栈上。我们可以使用 args(或 use a) 来打印当前活动函数的​​所有参数。我们可以使用 p 命令来计算作为参数传递的表达式并打印结果。让我们看下面的调试。

示例 -

显示表达式

pdb 模块除了 ppp 之外,还提供了其他命令来告诉 pdb 显示表达式的值,如果值发生变化,则在执行停止时显示。让我们来理解下面的命令语法和描述。

命令语法描述
displaydisplay [expression]每次在当前帧中执行停止时,它会显示表达式的值(如果已更改)。如果未提供表达式,则显示当前帧的表达式。
undisplayundisplay[expression]它不再在当前帧中显示表达式。如果未提供表达式,它会删除当前帧的所有表达式。

Python Pdb 断点

当我们处理大型程序时,断点起着至关重要的作用。我们经常希望添加可能发生错误的断点数量。pdb 模块提供了 break 命令来实现这一点。让我们看看下面的语法。

语法 -

如果未给出文件名,则为行号 lineno,则使用当前源文件。第二个参数 condition 非常强大且重要。使用它,我们可以在 condition 存在时应用断点。如果我们传递第二个参数,则当表达式求值为 true 时,pdb 将中断。

让我们理解以下示例 -

示例 -

输出

> d:\python project\test_pdb.py(7)()
-> x = input("Enter first number : ")
(Pdb) break test_pdb.py:7
Breakpoint 1 at d:\python project\test_pdb.py:7
(Pdb) break test_pdb.py:8
Breakpoint 2 at d:\python project\test_pdb.py:8
(Pdb) break 
Num Type         Disp Enb   Where
1   breakpoint   keep yes   at d:\python project\test_pdb.py:7
2   breakpoint   keep yes   at d:\python project\test_pdb.py:8

管理断点

我们还可以使用 enable、disable 和 remove 命令来管理断点。disable 允许调试器在到达断点时不要停止,而 enable 则激活禁用的断点。

让我们理解以下示例 -

示例 -

输出

> d:\python project\test_pdb.py(7)()
-> x = input("Enter first string : ")
(Pdb) break test_pdb.py:7
Breakpoint 1 at d:\python project\test_pdb.py:7
(Pdb) break test_pdb.py:8
Breakpoint 2 at d:\python project\test_pdb.py:8
(Pdb) break   
Num Type         Disp Enb   Where
1   breakpoint   keep yes   at d:\python project\test_pdb.py:7
2   breakpoint   keep yes   at d:\python project\test_pdb.py:8
(Pdb) disable 2
Disabled breakpoint 2 at d:\python project\test_pdb.py:8
(Pdb) break
Num Type         Disp Enb   Where
1   breakpoint   keep yes   at d:\python project\test_pdb.py:7
2   breakpoint   keep no    at d:\python project\test_pdb.py:8

结论

在本教程中,我们介绍了 pdb 模块的基本和常用概念。我们学习了打印表达式、pdb 命令、如何使用断点、显示表达式以及实现了一些示例。调试有助于程序员逐行分析程序。Python 自带一个易于导入和使用的默认调试器。pdb 模块在调试中起着至关重要的作用,尤其是在我们处理大型程序时。