Numpy 用IPython进行调试

用IPython进行调试,有些事情没人愿意做,调试便是其中之一。但是,掌握调试技术还是非常有必要的。调试可能要耗费数小时时间,而且根据墨菲定律(Murphy’s law),你真正能留给调试的时间很可能会很少。因此,你要熟悉自己所用的调试工具,做相关的事情时要有计划、有条理。当你找到并修复一个bug后,应该立即做一个测试,这样至少能避免在相同的地方再经历一次痛苦的调试过程。我们将调试下面这段有bug的代码,其中的一条语句试图访问一个不存在的数组元素。

import numpy

a = numpy.arange(7)
print a[8]

IPython调试器的功能和标准的Python pdb调试器类似,但增加了TAB键代码补全和语法突出显示等特性。

具体步骤

下面的步骤展示了一个典型的调试过程。

  1. 在IPython中运行有bug的脚本。

开启一个IPython shell。用如下命令在IPython中运行有bug的脚本。

In [1]: %run buggy.py

------------------------------------------------------------------
IndexError                                                        Traceback (most recent call last)
.../site-packages/IPython/utils/py3compat.pyc in execfile(fname,*where)
    173         else:
    174             filename = fname
--> 175         __builtin__.execfile(filename, *where)

.../buggy.py in ()
    2
    3 a = numpy.arange(7)
----> 4 print a[8]

IndexError: index out of bounds

  1. 启动调试器。

既然程序已经崩溃,我们可以启动调试器了。错误所在的行会被自动设置一个断点。

In [2]: %debug
> .../buggy.py(4)()
      2
      3 a = numpy.arange(7)
----> 4 print a[8]

  1. 列出代码。

可以使用list(或l)命令列出代码。

ipdb> list
      1 import numpy
      2
      3 a = numpy.arange(7)
----> 4 print a[8]

  1. 在当前行评估代码。

我们可以在当前行(即调试器当前指向的行)评估或执行任意的代码。

ipdb> len(a)
7

ipdb> print a
[0 1 2 3 4 5 6]

  1. 查看调用栈。

调用栈包含了正在运行的程序中处于活动状态的函数的信息。可以使用bt命令查看调用栈。

ipdb> bt
.../py3compat.py(175)execfile()
    171        if isinstance(fname, unicode):
    172         filename = fname.encode(sys.getfilesystemencoding())
    173     else:
    174         filename = fname
--> 175     __builtin__.execfile(filename, *where)
> .../buggy.py(4)()
0 print a[8]

在调用栈中返回到上一级。

ipdb> u
> .../site-packages/IPython/utils/py3compat.py(175)execfile()
      173             else:
      174                 filename = fname
  --> 175             __builtin__.execfile(filename, *where)

在调用栈中进入到下一级。

ipdb> d
> .../buggy.py(4)()
      2
      3 a = numpy.arange(7)
----> 4 print a[8]

攻略小结

本章介绍了怎样使用IPython调试一个NumPy程序。我们设置了一个断点,并且能定位到调用栈中的适当位置。本章用到了下列调试命令。

命令 功能描述
list或l 列出源代码
bt 显示调用栈
u 在调用栈中返回到上一级
d 在调用栈中进入到下一级

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程