最近在使用spyder做Python的数据可视化,中间想要调试的时候,发现spyder自带的断点设置,和调试功能总是在报错,更头大的是,搜索报错的处理方案,也没有什么好的解决方案。程序的函数定义比较多,只能用print打印函数的内部变量看,很不舒服。
报错信息如下:
’TypeError: runfile() got an unexpected keyword argument 'current_namespace'‘
在搜索解决方案的过程中,发现了pdb和ipdb,可以用于Python调试。学习内容,记录如下:
参考链接:Python 调试器 - pdb、ipdb - 简书
pdb,ipdb的区别
ipdb 之于 pdb,就像 ipython 之于 python,实现的功能相同,但 ipdb 具有语法高亮、 tab 补全、更友好的堆栈信息等优势。
pdb 是 Python 的标准库,无需安装直接使用,ipdb 为第三方库,需要使用 pip 安装后使用。
安装
pip3 install -i https://pypi.doubanio.com/simple ipdb
启动
下面,我们启动 Python 调试器,有以下 2 种方式:
通过命令行启动
通过命令行启动 Python 调试器,只需要在命令行参数指定使用 pdb 模块启动 Python 脚本即可:
python -m pdb xxx.py
这种方式适用于程序文件较短的情景,运行上述命令,将在 Python 源码的第一行启动 Python 调试器。
在代码中添加断点pdb.set_trace()
另一种方法是在 Python 代码中调用 pdb 模块的 set_trace 方法设置一个端点。当程序执行至断点时,将会暂停执行并打开 pdb 调试器。
下面,我们以一段简短的程序为例,来实践上文介绍的 pdb 命令。代码如下:
from __future__ import print_function
import pdb
def num_sum(n):
s = 0
for i in range(n):
pdb.set_trace()
s += i
print('****** {} *****'.format(s))
if __name__ == '__main__':
num_sum(10)
我们在 for
循环内部的第一行使用 pdb.set_trace()
来设置了一个断点,当程序运行至改行时将暂停执行,并运行 Python 调试器。
接下来可以尝试以下操作熟悉命令行。
- 使用
where
/bt
/w
命令来查看当前函数的调用堆栈 - 使用
list
命令可以打印源码 - 使用
pp
/p
可以打印任意变量的当前取值(pp按格式展开打印,例如json数据) n
向下执行1行(next)- c(continue) 命令继续执行至下一个断点
常用的ipdb命令
常用 ipdb 命令如下:
h(help)
:帮助命令s(step into)
:执行下一行,下一行是子程序时,将进入子程序执行n(next)
:执行下一行,但不会进入子程序b(break)
:b line_number
打断点cl(clear)
: 清除断点c(continue)
: 一直执行到断点r(return)
: 从当前函数返回j(jump)
:j line_number
,跳过代码片段,直接执行指定行号所在的代码l(list)
: 列出上下文代码a(argument)
: 列出传入函数所有的参数值p/pp
:print
和pretty print
打印出变量值r(restart)
: 重启调试器q(quit)
: 推出调试,清除所有信息bt / w(where)
: 打印堆栈轨迹u(up)
移动到上一层堆栈d(down)
移动到下一层堆栈enable
: 启用禁用的断点disable
: 禁用启用的断点