python程序的调试模式

关于debug模式的更多细节,可参阅在线文档 https://docs.python.org/zh-cn/3/library/pdb.html

一、设置断点

1、使用 breakpoint() 函数

Python 3.7 引入了内置函数 breakpoint(),它用于在代码中设置断点。当程序执行到 breakpoint() 时,会自动进入调试模式,允许开发者交互式地检查变量、执行代码和调查程序状态。
程序中断后可使用调试命令查看变量值,跟踪进函数,参见下面的调试命令。
breakpoint() 函数等效于 import pdb; pdb.set_trace()

2、使用 pdb 模块(侵入式代码)

pdb(Python Debugger)是 Python 的标准库模块,用于进行交互式调试。它提供了丰富的功能,允许开发者在代码中设置断点、检查变量、执行代码等。
要在代码中设置断点,首先需要导入 pdb 模块,然后在需要断点的位置调用 pdb.set_trace() 函数。

import pdb

def calculate_product(a, b):
    result = a * b
    pdb.set_trace()  # 设置断点
    return result

x = 5
y = 3
result = calculate_product(x, y)
print(f"The product of {x} and {y} is {result}")

当程序执行到 pdb.set_trace() 处时,会进入交互式调试模式。

3. pdb 命令行调试

除了在代码中设置断点外,还可以使用 pdb 命令行工具来调试 Python 脚本。只需在命令行中运行以下命令:

python -m pdb my_script.py

这将启动 pdb 调试器,并在脚本的第一行设置一个断点。可以使用 pdb 命令行工具中的命令进行交互式调试。

二. 交互式调试命令

在 pdb 的交互式调试模式中,可以使用一系列命令来检查变量、执行代码和探查程序状态。

以下是一些常用的 pdb 命令:

帮助

h(elp) [command]
不带参数时,显示可用的命令列表。参数为 command 时,打印有关该命令的帮助。

查看源代码

l(ist) [first[, last]]
列出当前文件的源代码。如果不带参数,则列出当前行周围的 11 行,或延续前一次列出。如果用 . 作为参数,则列出当前行周围的 11 行。如果带有一个参数,则列出那一行周围的 11 行。如果带有两个参数,则列出所给的范围中的代码;如果第二个参数小于第一个参数,则将其解释为列出行数的计数。
当前帧中的当前行用 -> 标记。如果正在调试异常,且最早抛出或传递该异常的行不是当前行,则那一行用 >> 标记。

断点

添加断点
b(reak) [([filename:]lineno | function) [, condition]]
在指定的行号或函数首行中断,如果参数 condition 存在,它应该是一个表达式,且它的计算值为 true 时断点才起作用。
如果不带参数执行,将列出所有中断,包括每个断点、命中该断点的次数、当前的忽略次数以及关联的条件(如果有)。

添加临时断点
tbreak [([filename:]lineno | function) [, condition]]
语法同 b 命令,执行一次后时自动删除断点(这就是它被称为临时断点的原因)

清除断点
cl(ear) [filename:lineno | bpnumber ...]
如果参数是 filename:lineno,则清除此行上的所有断点。如果参数是空格分隔的断点编号列表,则清除这些断点。如果不带参数,则清除所有断点(但会先提示确认)。

disable bpnumber [bpnumber ...]
禁用断点,断点以空格分隔的断点编号列表给出。禁用断点表示它不会导致程序停止执行,但是与清除断点不同,禁用的断点将保留在断点列表中并且可以(重新)启用。

enable bpnumber [bpnumber ...]
启用指定的断点。

ignore bpnumber [count]
为指定的断点编号设置忽略次数。 如果省略 count,则忽略次数将设置为 0。 当忽略次数为零时断点将变为活动状态。 如果为非零值,则在每次到达断点且断点未禁用且关联条件取真值时 count 就像递减。

condition bpnumber [condition]
为断点设置一个新 condition,它是一个表达式,且它的计算值为 true 时断点才起作用。如果没有给出 condition,则删除现有条件,也就是将断点设为无条件。

查看

p(rint) expression
在当前上下文中对 expression 求值并打印该值。

pp expression
与 p 命令类似,但 expression 的值将使用 pprint 模块美观地打印。

whatis expression
打印 expression 的类型。

source expression
尝试获取 expression 的源代码并显示它,经尝试,expression 可以是函数名。

a(rgs)
打印当前函数的参数及其当前的值。

w(here)
打印栈回溯,最新的帧位于底部。 有一个箭头 (>) 指明当前帧,该帧决定了大多数命令的上下文

display [expression]
如果 expression 的值发生变化则显示它的值,每次都会停止执行当前帧。
如果不带 expression,则列出当前帧的所有显示表达式。
显示 expression 的值并与 expression 之前的求值结果进行比较,因此当结果可变时,显示可能无法体现变化,可以通过拷贝机制巧妙地实现此功能,如display lst[:]

undisplay [expression]
不再显示当前帧中的 expression。 如果不带 expression,则清除当前帧的所有显示表达式。

执行控制

逐行执行

s(tep)
执行下一行(能够进入函数体)

n(ext)
执行下一行(不会进入函数体)

r(eturn)
执行下一行(在函数中时会直接执行到函数返回处)

非逐行执行

c(ont(inue))
继续运行,仅在遇到断点时停止。

j(ump) lineno
设置即将运行的下一行。仅可用于堆栈最底部的帧。它可以往回跳来再次运行代码,也可以往前跳来跳过不想运行的代码。

unt(il) [lineno]
如果不带参数,则继续运行,直到行号比当前行大时停止。
如果带有 lineno,则继续执行直至行号大于或等于 lineno。 在这两种情况下,在当前帧返回时也将停止。需要注意的是,不是所有的跳转都是允许的:例如,不能跳转到 for 循环的中间或跳出 finally 子句。

调试控制

run [args ...]
restart [args ...]
重启被调试的 Python 程序。 如果提供了 args,它会用 shlex 来拆分且拆分结果将被用作新的 sys.argv。 历史、中断点、动作和调试器选项将被保留。 restart 是 run 的一个别名。

q(uit)
退出调试器。 被执行的程序将被中止。

posted @ 2024-07-09 10:57  汉学  阅读(183)  评论(0)    收藏  举报