Python 调试工具 pudb 的使用指南
admin
2023-07-31 00:30:10
0

最近在调试python程序,对于这种动态语言,我之前的方法大多都是打tag,真是痛苦的要死。话说回来,debug是为了什么?debug可以看成是对我们的猜测的一种验证。如果我们能通过工具将需要的信息(变量、堆栈)都显示出来,调试就很有效率。下面就介绍一个python调试工具:pudb。

本文部分内容参考自Professor Norm Matloff的文章,我特此发了邮件给他征得了翻译的权限。

Professor Norm Matloff, that is very nice of you, and thanks.

pudb是全屏的基于控制台的可视化调试器。如果你还记得Turbo C的话,看到这个你应该会感到亲切的。Homepage

pudb

先概要看一下pudb的特性:

  • 源码语法高亮,栈、断点、变量可见并且一直动态更新。变量展示还有很多可以定制化的功能。
  • 基于键盘,简单高效。为什么说高效呢?因为它支持VI的鼠标移动。还支持PDB的某些命令
  • 支持查找源代码,可以使用m代用module browser查看载入的模块
  • 断点设置:鼠标移到某行代码,按b,然后可以在断点窗口编辑断点
  • PuDB看重异常处理,post-mortem模式使折回到crash的最后一步更简单

安装

123 pip install pudboreasy_install pudb

使用

为了支持pudb,需要在代码中插入

123 from pudb import set_trace; set_trace()orimport pudb; pu.db

然后通过下面命令启动pudb

1 pudb myscript.py

step by step

我们以下面这段二分程序binsearch.py为例子

123456789101112131415161718192021 import pudb; pu.db def findinspt(x, xnew):    n = len(x)    lo = 0    hi = n1    while True:        mid = (lo + hi) / 2        if xnew > x[mid]:            lo = mid + 1        else:            hi = mid        if xnew == x[mid]:            return mid if __name__ == \”__main__\”:    y = [5,12,13]    print findinspt(y,3)    print findinspt(y,8)    print findinspt(y,12)    print findinspt(y,30)

运行下面命令

1 pudb binsearch.py

不出意外会得到下面的窗口,左半边是源代码,右边一次是变量窗口、程序调用栈、断点

先介绍几个简单命令,不需要记住,因为下面会多次提到

  • n: next,也就是执行一步
  • s: step into,进入函数内部
  • c: continue
  • b: break point,断点
  • !: python command line
  • ?: help

最重要的是记住?,需要的时候按”?”查询
我们按一下n会发现y=[5,12,13]这行代码高亮显示了,表示执行到了这行代码。

再按一下n,y=[5,12,13]这行代码就执行完了,仔细看会发现右上角的变量窗口出现了y:list,表示程序内存中有了变量y。后面的List是type。

要查看y的值,按s即可。但是如果这个时候你要是不小心按到了Enter,你会发现下面的界面。

对的,这就是有关变量的所有信息。你只需要将光标移动到你要查看的信息,比如 Show repr(),按’Enter’键,再移动向右方向键到ok上,再按Enter键,就可以查看相应的信息的。但是如果你查看了变量不存在的信息,就会出现下面的画面。

当光标停在函数上的时候可以选择n执行到下一行代码,或者s进入函数内部。正常如果有终端输出的时候,pudb会回到终端。但是我在mac上并没有回去,有待进一步验证。这个时候我们执行n的时候,如果函数有问题,会出现异常:[PROCESSING EXCEPTION – hit e to examine]。按e就会显示异常的具体信息。

下面就是进入函数进行调试了。先按q选择restart重启pudb,执行到上面异常的哪一行选择s进入函数内部。这个时候findinspet()函数内部的变量就会显示在右上角变量窗口中。按n单步调试一会,发现lo,hi都变成0了。说明出现问题了。

修改程序。

1234567891011121314151617181920212223 import pudb; pu.db def findinspt(x, xnew):    n = len(x)    lo = 0    hi = n1    while True:        mid = (lo + hi) / 2        if xnew > x[mid]:            lo = mid + 1        else:            hi = mid        if xnew == x[mid]:            return mid        if lo == hi:            return lo if __name__ == \”__main__\”:    y = [5,12,13]    print findinspt(y,3)    print findinspt(y,8)    print findinspt(y,12)    print findinspt(y,30)

重新启动pudb。光标到main,按c会得到如下界面。

这时候选择restart,然后按o就可以看到输出结果了。

结果对于3,8,12都是对的,30的插入位置不对。为了让debug效率更高,下面使用断点功能。使用向下方向键,光标移动到第13行,按b即在该行设置了断点,右下角的断点显示窗口可以看到。

但是我们只想debug当xnew等于30的时候的情况。先使用向右方向键,再使用向下方向键到断点显示窗口的断点上,按Enter。下图。在condition的右侧设置条件xnew==30,点击OK保存。

使用方向键切换到左侧源码部分,先按n单步执行到main主程序,然后按c,程序就执行到了断点位置处。从右侧可以看到xnew的值为30。

这个时候就可以根据我们需要来单步调试了。对于本文的程序,会发现需要对边界条件处理一下。程序改为下面即可。

1234567891011121314151617181920212223242526 import pudb; pu.db def findinspt(x, xnew):    n = len(x)    lo = 0    hi = n1    while True:        mid = (lo + hi) / 2        if xnew > x[mid]:            lo = mid + 1        else:            hi = mid        if xnew == x[mid]:            return mid        if lo == hi:            if xnew <= x[lo]:                return lo            else:                return lo if __name__ == \”__main__\”:    y = [5,12,13]    print findinspt(y,3)    print findinspt(y,8)    print findinspt(y,12)    print findinspt(y,30)

到此,基本上涉及了Debug的一些主要情况。如果说最后的程序是一个产品,Debug就是产品出问题时候的用来解决问题的工具。使用工具的效率一定程度也决定了产品的生产效率。

相关内容

热门资讯

500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
python绘图库Matplo... 本文简单介绍了Python绘图库Matplotlib的安装,简介如下: matplotlib是pyt...
Prometheus+Graf... 一,Prometheus概述 1,什么是Prometheus?Prometheus是最初在Sound...