方便的开发工具

本节介绍几个在开发和调试程序时经常会用到的工具软件,熟练掌握它们的用法能够起到事半功倍的效果。为了展示工具软件的功能,本节使用了一些扩展库作为演示。读者可以暂时忽略这些扩展库的用法,在后续的章节中会对它们进行详细介绍。

IPython

IPython是一个Python的交互式命令行工具,与Python自带的命令行相比,它更容易使用,功能也更强大。它支持语法高亮、自动补全、自动缩进,并且内置了许多有用的功能和函数。

如果读者安装了Python(x,y),可以从它的启动界面中运行IPython,如【图:通过Python(x,y) Home启动IPython的各种选项】所示。

/tech/static/books/scipy/_images//iPython_start.png

通过Python(x,y) Home启动IPython的各种选项

从下拉选择框中选择想运行的命令行配置,然后点击右侧的❶或者❷按钮运行所选的命令行配置。其中,“Python”选项运行Python自带的命令行工具,而“IPython(x,y)”、“IPython(Qt)”、“IPython(wxPython)”、“IPython(mlab)”和“IPython(sh)”等几个选项,它们分别使用如下的参数运行IPython:

选项 参数
IPython(x,y) -pylab -p xy
IPython(Qt) -q4thread
IPython(wxPython) -wthread
IPython(mlab) -wthread -p mlab
IPython(sh) -q4thread -p sh

点击❶按钮将用一个名为Console的软件启动命令行,此软件使用Windows的窗口界面包装命令行界面,并且具有标签页功能。点击❷按钮用Windows自带的命令行界面启动。

如果运行“IPython(x,y)”,在启动IPython之后将自动运行一个名为“default.py”脚本文件。此脚本缺省执行以下的函数库导入:

import numpy
import scipy
from numpy import *

为了与NumPy、SciPy社区的推荐导入方式一致,请点击按钮❸,在所打开的文件夹中添加一个名为“myimports.py”的文件,并在其中添加如下几行程序:

import numpy as np
import scipy as sp
import pylab as pl

此后运行“IPython(x,y)”的时候请选择“myimports.py”为启动脚本。

如果要在命令行中和matplotlib、TraitsUI、Mayavi等图形界面程序进行交互,需要给IPython传递“-wthread”、“-q4thread”或者“-pylab”参数。当使用“pylab”参数时,在调用matplotlib库的绘图函数进行绘图时,将立即显示图表。

下面我们以matplotlib绘图为例,实际操作一下。请读者选择“myimports.py”为启动脚本,并运行IPython(x,y)命令行。然后在命令行中输入下面的语句,如果一切顺利,将会立即显示出如【图:使用IPython交互式地绘制正弦波】所示的正弦波形。

>>> x = np.linspace(0, 4*np.pi, 100)
>>> pl.plot(x, np.sin(x))

这里的np和pl是运行“myimports.py”之后的结果,它们分别表示numpy和pylab模块。由于IPython(x,y)的命令行参数中有“-pylab”,pylab模块中的所有符号也会被载入到当前的名字空间中,因此也可以用下面的程序绘制正弦波形:

>>> x = linspace(0, 4*pi, 100)
>>> plot(x, sin(x))
/tech/static/books/scipy/_images//iPython_sample.png

使用IPython交互式地绘制正弦波

本书中所有在IPython下输入的代码都用“>>> ”作为提示符,而不用在IPython命令行的缺省提示符:“In[..]”。

在IPython中,可以很方便地使用如下功能:

  • 自动补全:输入一部分文字之后按Tab键,IPython将列出所有补全信息。用此功能可以快速输入对象的属性名或者进行文件名补全。
  • 查看文档:输入需要查看文档的函数名,然后在后面添加一个或者两个问号。“?”表示查看函数的文档,“??”表示查看其Python源代码,如果函数不是用Python编写,则查看不到其源代码。
  • 执行Python程序:用run命令运行指定的Python程序文件。缺省是在一个新的环境中运行程序,当程序退出时将程序的运行环境中的对象复制到IPython的环境中。如果运行run命令时添加“-i”参数,则在IPython的当前环境中执行程序,即程序可以直接访问IPython环境中的对象。
  • 执行剪切板中的程序:运行paste命令将在IPython环境中运行剪贴板中的程序代码,它会自动删除代码中的提示符“>>>”。运行“paste foo”将把剪切板中的内容复制到变量foo中。变量foo是IPython提供的SList列表类型,它提供了很多对其内容进行操作的方法。
  • 执行系统命令:在要执行的系统命令之前添加一个“!”号。例如如果执行“!test.py”,那么操作系统会运行“test.py”文件。和run命令不同,“test.py”将在另外的进程中运行。

在IPython中使用run命令运行Python程序能够提高调试程序的速度。因为每次运行用户程序时,IPython环境没有初始化,已经载入的模块不需要重新载入,对于NumPy、SciPy和matplotlib这样比较庞大的库,能节省不少载入时间。下面是一个例子:

01-intro/speedup_test.py

载入numpy、scipy和pylab等库并绘制一个简单的频率扫描波

import numpy as np
from scipy import signal
import pylab as pl

t = np.linspace(0, 10, 1000)
x = signal.chirp(t, 5, 10, 30)
pl.plot(t, x)
pl.show()

此程序计算频率扫描波并使用图表显示,如果通过双击或者在命令行中输入文件名直接运行此程序,需要等几秒钟才能看到结果。如果我们先在“speedup_test.py”所在的文件夹启动IPython,然后运行:

>>> run speedup_test.py

第一次运行时由于同样需要载入所需的模块,所需的时间和直接运行没有差别,但是再次运行时由于不需要载入模块,结果可以立即显示出来。此后还可以在IPython中输入程序,查看变量的值或者修改界面的各种属性,例如:

>>> x[:5] #查看扫描波的前5个值
array([ 1.        ,  0.95076436,  0.80716308,  0.58242516,  0.29822084])
>>> pl.gca().lines[0].set_color("r") #设置曲线颜色为红色
>>> pl.draw() #刷新界面

Python的模块缓存功能虽然可以加速程序运行,但是也会带来一些问题。例如如果有一个名为“mymodel.py”的模块,在“usemodel.py”中导入mymodel模块,那么只有在第一次运行“run usemodel.py”时会载入mymodel模块,以后即使“mymodel.py”文件发生改变,Python也不会重新载入最新的模块。如果要修改调试“mymodel.py”中的程序,就需要在“usemodel.py”中添加如下两行:

import mymodel
reload(mymodel)

这样每次运行“usemodel.py”时都会强制重新载入mymodel模块。

mymodel.py , usemodel.py

使用reload函数重新载入模块

IPython还有很强大的调试功能,例如下面的程序使用\sin(x \cos(x))计算一个长度为10000的数组,并且调用imshow()将此数组显示成一个二维图像。

01-intro/ipython_debug.py

用IPython调试程序中的错误

import pylab as pl
import numpy as np

def test_debug():
    x = np.linspace(1, 50, 10000)
    img = np.sin(x*np.cos(x))
    pl.imshow(img)
    pl.show()

test_debug()

但是由于程序中有错误, 在IPython中运行它时,出现很长一串错误信息,下面给出的是错误信息的最后一部分,我们看到抛出异常的是“image.pyc”中的set_data()函数,它是扩展模块中的一个函数,错误信息的意思是作为图像数据的数组的维数不正确。

>>> run ipython_debug.py
[[省略]]
    C:\Python26\lib\site-packages\matplotlib\image.pyc in set_data(self, A)
    298         if (self._A.ndim not in (2, 3) or
    299             (self._A.ndim == 3 and self._A.shape[-1] not in (3, 4))):
--> 300             raise TypeError("Invalid dimensions for image data")
    301
    302         self._imcache =None
    TypeError: Invalid dimensions for image data
    WARNING: Failure executing file: <ipython_debug.py>

为了找到我们的程序中出错的位置,在IPython中输入debug命令,进入调试状态,并显示出调用堆栈的当前位置。

>>> debug
> c:\python26\lib\site-packages\matplotlib\image.py(300)set_data()
    299             (self._A.ndim == 3 and self._A.shape[-1] not in (3, 4))):
--> 300             raise TypeError("Invalid dimensions for image data")
    301
ipdb>

调试状态的提示符为“ipdb”,输入“h”命令可以查看调试状态下所能用的所有命令,输入“h 命令名”可以查看命令的详细说明。连续执行多次“u”命令,沿着调用堆栈往上溯源,直到找到“ipython_debug.py”中出错的那一行:

ipdb> u
> c:\zhang\pydoc\source\examples\01-intro\ipython_debug.py(7)test_debug()
      6     img = np.sin(x*np.cos(x))
----> 7     pl.imshow(img)
      8     pl.show()

由错误信息可知数组img的维数不对。查看表示数组维数的ndim属性发现img是一维数组,而imshow()的参数应该是二维数组:

ipdb> img.ndim
1

输入“q”命令结束调试,并编辑“ipython_debug.py”,在调用imshow()之前添加下面的一行程序:

img.shape = 100, -1

然后再重新执行程序,这次就可以看到表示二维数组的图像了。

>>> run ipython_debug.py

Spyder

Spyder是Python(x,y)的作者为它开发的一个简单的集成开发环境。和其它的Python开发环境相比,它最大的优点就是模仿MATLAB的“工作空间”的功能,可以很方便地观察和修改数组的值。【图:在Spyder中执行图像处理的程序】是Spyder的界面截图。

http://code.google.com/p/spyderlib

Spyder项目的地址

/tech/static/books/scipy/_images//spyder_interface.png

在Spyder中执行图像处理的程序

Spyder的界面由许多泊坞窗口(Dock Window)构成,用户可以根据自己的喜好调整它们的位置和大小。当多个窗口在一个区域中时,将使用标签页的形式显示。例如在【图:在Spyder中执行图像处理的程序】中,我们可以看到“Editor”、“Object inspector”、“Variable explorer”、“File explorer”、“Console”、“History log”以及两个显示图像的窗口。在View菜单中可以设置是否显示这些窗口。下表列出了Spyder的主要窗口及其作用:

窗口名 功能
Editor 编辑程序,可用标签页的形式编辑多个程序文件
Console 在别的进程中运行的Python控制台
Variable explorer 显示Python控制台中的变量列表
Object inspector 查看对象的说明文档和源程序
File explorer 文件浏览器,用于打开程序文件或者切换当前路径

按F5将运行当前编辑器中的程序。第一次运行程序时,将弹出一个如【图:运行配置对话框】所示的运行配置对话框。在此对话框中可以对程序的运行进行如下配置:

  • Command line options:输入程序的运行参数。
  • Working directory:输入程序的运行路径。
  • Execute in current Python or IPython interpreter:在当前的Python控制台中运行程序。程序可以访问此控制台中的所有全局对象,控制台中已经载入的模块不需要重新载入,因此程序的启动速度较快。
  • Execute in a new dedicated Python interpreter:新开一个Python控制台并在其中运行程序,程序的启动速度较慢,但是由于新控制台中没有多余的全局对象,因此更接近实际的运行情况。当选择此项时,还可以勾选“Interact with the Python interpreter after execution”,这样当程序结束运行时,控制台进程继续运行,因此可以通过它查看程序运行之后的所有的全局对象。此外,还可以在“Command line options”中输入新控制台的启动参数。

运行配置对话框只会在第一次运行程序时出现,如果想修改程序的运行配置,可以按F6打开运行配置对话框。

/tech/static/books/scipy/_images//spyder_run_dialog.png

运行配置对话框

控制台中的全局对象可以在“Variable explorer”窗口中找到。此窗口支持数值、字符串、元组、列表、字典以及NumPy数组等对象的显示和编辑。【图:使用“Variable explorer”查看和编辑数组的内容】(左)是“Variable explorer”窗口的截图,列出了当前控制台中的变量名、类型、大小以及其内容。右键点击变量名弹出对此变量进行操作的菜单。在菜单中选择Edit选项,弹出【图:使用“Variable explorer”查看和编辑数组的内容】(右)所示的数组编辑窗口。此编辑窗口中的单元格的背景颜色直观地显示了数值的大小。

当有多个控制台运行时,“Variable explorer”窗口显示当前控制台中的全局对象。
/tech/static/books/scipy/_images//spyder_workspace_01.png

使用“Variable explorer”查看和编辑数组的内容

选择菜单中的Plot选项,将弹出如【图:在“Variable explorer”中将数组绘制成曲线图】所示的绘图窗口。在绘图窗口的右键菜单中选择“Parameters”,将弹出一个编辑绘图对象的对话框。图中使用此对话框修改了曲线的颜色和线宽。

/tech/static/books/scipy/_images//spyder_workspace_02.png

在“Variable explorer”中将数组绘制成曲线图

Spyder的功能比较多,这里仅介绍一些常用的功能和技巧:

  • 缺省配置下,“Variable explorer”中不显示大写字母开头的变量,可以点击其工具栏中的配置按钮(最后一个按钮),在菜单中取消“Exclude capitalized references”的勾选状态。
  • 在控制台中,可以按Tab按键进行自动补全。在变量名之后输入“?”,可以在“Object inspector”窗口中查看对象的说明文档。此窗口的Options菜单中的“Show source”选项可以开启显示函数的源程序。
  • 可以通过“Working directory”工具栏修改工作路径,用户程序运行时,将以此工作路径作为当前路径。例如我们只需要修改工作路径,就可以用同一个程序处理不同文件夹下的数据文件。
  • 在程序编辑窗口中按住Ctrl按键,并单击变量名、函数名、类名或者模块名,可以快速跳转到其定义位置。如果是在别的程序文件中定义的,将打开此文件。在学习一个新的模块的用法时,我们经常会需要查看模块中的某个函数或者某个类是如何实现的,使用此功能可以帮助我们快速查看和分析各个模块的源程序。例如下面的程序从不同的扩展库载入了一些模块和类。用Spyder打开此文件,按住Ctrl按键,并点击signal、pl、HasTraits、Instance、View、Item、lfilter、plot、title等,将打开定义它们的程序文件,并跳转到相应的行。

01-intro/gotodefine.py

测试定义跳转功能

from scipy import signal
import pylab as pl
from enthought.traits.api import HasTraits, Instance
from enthought.traits.ui.api import View, Item

signal.lfilter
pl.plot
pl.title

Wing IDE 101

Wing IDE是一个功能强大的Python集成开发环境,它的专业版是商业软件,但是也提供了一个免费的简装版本Wing IDE 101。

和Spyder一样,在Wing IDE中只需要按住Ctrl键并同时点击函数名或者类名,就能直接跳转到定义它的位置。此外,Wing IDE还有不错的调试功能。在程序中设置断点之后,点击Debug按钮就可以进入调试运行模式。当运行到断点之后,程序将暂停运行。读者可以用Wing IDE打开下面的程序,并将光标移到“self.count += 1”一行,按F9添加断点,然后按F5开始调试程序。

01-intro/wingide_debug.py

测试Wing IDE的断点调试功能

/tech/static/books/scipy/_images//wingide_debug.png

用Wing IDE 101调试程序

【图:用Wing IDE 101调试程序】是调试程序时的界面截图。程序执行之后会显示出一个小窗口,其中有一个名为“Click Me”的按钮,点击它将调用程序中的_button_fired(),遇到断点从而暂停程序运行。此时可以观察程序的调用堆栈(Call stack)和堆栈数据(Stack Data)。

在左侧的“Stack Data窗口”中,显示了locals和globals两个字典,它们分别是当前执行环境下的全局变量和当前堆栈位置中的局域变量。下半部分显示了被选中的名为self的局域变量的内容。在窗口的下方的“Call Stack窗口”显示了执行到断点处的调用堆栈,其中堆栈的顶部即最下面一行被选中。我们可以用鼠标选中堆栈中的其它调用点,程序编辑窗口和“Stack Data窗口”中的内容也随之发生变化。通过这种方法我们可以观察堆栈中的所有局域变量,了解运行到断点处的整个调用过程,并查看与其相关的源程序。

內容目录

上一个主题

安装软件包

下一个主题

函数库介绍

本页

loading...