python pu()_Python 调试工具 pudb 的使用指南

[strace是Linux环境下的一款程序调试工具,用来监察一个应用程序所使用的系统呼叫及它所接收的系统信息。strace是一个有用的小工具,它可以通过跟踪系统调用来让你知道一个

最近在调试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的特性:

源码语法高亮,栈、断点、变量可见并且一直动态更新。变量展示还有很多可以定制化的功能。

基于键盘,简单高效。为什么说高效呢?因为它支持VI的鼠标移动。还支持PDB的某些命令

支持查找源代码,可以使用m代用module browser查看载入的模块

断点设置:鼠标移到某行代码,按b,然后可以在断点窗口编辑断点

PuDB看重异常处理,post-mortem模式使折回到crash的最后一步更简单

安装

Python

pip install pudb

or

easy_install pudb

使用

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

from pudb import set_trace; set_trace()

or

import pudb; pu.db

然后通过下面命令启动pudb Python

pudb my-script.py

step by step

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

Python

import pudb; pu.db

def findinspt(x, xnew):

n = len(x)

lo = 0

hi = n-1

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)

运行下面命令 Python

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了。说明出现问题了。

修改程序。 Python

import pudb; pu.db

def findinspt(x, xnew):

n = len(x)

lo = 0

hi = n-1

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。

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

import pudb; pu.db

def findinspt(x, xnew):

n = len(x)

lo = 0

hi = n-1

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就是产品出问题时候的用来解决问题的工具。使用工具的效率一定程度也决定了产品的生产效率。[这是对上一篇关于调试器的文章的一个小小的补充。 标准库有三种分析方法(cProfile和profile,hotshot)以及不计其数的第三方可视化工具,转化器,以及诸如此类的东西。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值