Python Debugger
pdb
The Python Debugger Pdb
可以直接在命令行中启动,调试程序
也可以写在代码中
命令行使用
可以直接在命令行指定要进行调试的程序
python -m pdb my_test.py
之后会显示当前代码执行的位置
通过输入命令进行操作
命令
命令 | 作用 |
---|---|
h(elp) | 帮助 |
w(here) | 打印当前堆栈 |
d(own)[count] | 执行跳转到当前堆栈的深 [count] 层,默认为 1 |
u(p) | 执行跳转到当前堆栈的上 [count] 层,默认为 1 |
b(reak)[ ([filename:]lineno | function) [, condition] ] |
不加参数:列出所有断点; 指定行号:(可以指定其他文件的一行) 在当前行添加断点; 指定函数:在函数的第一个可执行语句添加断点; 指定条件:当条件语句满足时断点生效 |
tbreak[ ([filename:]lineno | function) [, condition] ] | 临时断点,生效一次后自动删除,使用方法同 b(reak) |
cl(ear) |
不加参数:清除所有断点; 指定行号:(可以指定其他文件的一行) 清除当前行断点; 指定断点号:清除此断点 |
disable bpnumber [bpnumber ...] | 停用断点 |
enable bpnumber [bpnumber ...] | 激活断点 |
condition bpnumber [condition] | 为此断点设定条件 |
s(tep) | 执行下一条命令,如果是函数调用,就执行到调用函数的第一句(会进入到调用的函数内部) |
n(ext) | 执行下一条语句,如果是函数调用,就执行函数,之后执行下一条语句(不会进入调用的函数内部) |
unt(il) [lineno] | 不带参数的情况下,继续执行,直到到达行号大于当前行的行号为止。使用[lineno],继续执行直到行号大于或等于[lineno]。 |
r(eturn) | 继续执行,直至当前函数 return |
retval | 打印函数最后一次的返回值 |
run [args...] | 重新启动程序,相当于restart |
c(ont(inue)) | 继续执行,直至遇到断点 |
l(ist) |
列出当前语句周围 11 行的源码。 如果有一个参数,列出该行号周围 11 行的源码。 如果有两个参数,列出区间内的源码。 如果有两个参数,且后面的小,前面的参数为行号,后面参数为列出源码的行数。 |
longlist | ll | 列出当前函数的全部源码 |
a(rgs) | 列出当前函数的所有参数 |
whatis arg | 打印参数类型 |
p expression | 输出 expression 的值 |
pp expression | 好看一点地输出 expression 的值 |
q(uit) exit | 退出 debugger 停止执行语句 |
set_trace
set_trace() 是最常用的断点方式,放置在代码中,程序会停在断点处,输入命令 c
继续运行
示例:
import pdb
def main(i):
for i in range(i):
pdb.set_trace()
print(i)
if __name__ == '__main__':
main(10)
输出:
> /dir/test.py(7)main()
-> print(i)
(Pdb)
表示执行到 /dir/test.py
的第 7 行,main()
函数中,语句为 print(i)
breakpoint()
Python 3 中加入了内置函数 breakpoint()
可以直接调用 pdb,相当于 pdb.set_trace()
run & runeval
会在当前位置打断点,接下来会执行字符串类型的表达式
用法
run(cmd, globals=None, locals=None) 会对传入的参数执行 exec()
runeval(expr, globals=None, locals=None) 会对传入的参数执行 eval()
如果不传入参数,则默认使用全局变量(__main__.dict
)
如果要传入参数就要将全部参数以字典形式传入,使用没有传入的参数会报错