“你的Python开发环境是什么?”
“IPython外加一个文本编辑器。”
这个经典的问答来自著名的python数据处理包pandas的作者Wes McKinney. IPython作为python的交互式计算和开发环境,”生产力”是他最大的特点。下面简单介绍一些IPython的生产力特性。
1. Tab键自动补全
可补全内容包括:变量名、函数名、成员变量函数、目录文件。
2. 内省
在变量的前面或后面加上一个问号(?)就可以将有关该对象的一些通用信息显示出来。
In [1]: b = [1, 2, 3]
In [2]: b?
Type: list
String form: [1, 2, 3]
Length: 3
Docstring:
list() -> new empty list
list(iterable) -> new list initialized from iterable's items
可以用?来显示docstring, 使用??还将显示对应的源代码。
另外?还有一个用法,即搜索IPython命名空间,类似于标准UNIX或Windows命令行中的那种用法。一些字符再配以通配符(*)即可显示出所有与该通配符表达式相匹配的名称。例如,我们可以列出NumPy顶级命名空间中含有”load”的所有函数:
In [9]: np.*load*?
np.load
np.loads
np.loadtxt
np.pkgload
3. %run命令
用%run
运行的python脚本在一个空的命名空间中运行,运行结束后所定义的全部变量可以在当前的IPython shell中访问。
4. 执行剪贴板中的代码
有的代码直接粘贴进来会出问题,于是%cpaste
就派上用场了。
%cpaste
在粘贴完成后输入一行’–‘或者按ctrl-d即可
5. 魔术命令
IPython有一些特殊命令,有的为常见任务提供便利,有的则使你能够轻松控制IPython系统的行为。魔术命令是以百分号%为前缀的命令。
例如,用%timeit
检测Python语句的执行时间
In [10]: a = np.random.randn(100, 100)
In [11]: %timeit np.dot(a, a)
The slowest run took 70.39 times longer than the fastest. This could mean that an intermediate result is being cached
10000 loops, best of 3: 82.2 us per loop
魔术命令可以用?查看其用法。
魔术命令默认是可以不带百分号%使用的,只要没有定义与其同名的变量即可。这个技术叫做automagic,可以通过%automagic
打开或关闭。
附上常用的Python魔术命令。
命令 | 说明 |
%quickref |
显示IPython的快速参考 |
%magic |
显示所有魔术命令的详细文档 |
%debug |
从最新的异常跟踪的底部进入交互式调试器 |
%hist |
打印命令的输入(可选输出)历史 |
%pdb |
在异常发生后自动进入调试器 |
%paste |
执行剪贴板中的Python代码 |
%cpaste |
打开一个特殊提示符以便手工粘贴待执行的Python代码 |
%reset |
删除interactive命名空间中的全部变量/名称 |
%page OBJECT |
通过分页器打印输出OBJECT |
%run script.py |
在IPython中执行一个Python脚本文件 |
%prun statement |
通过cProfile执行statement,并打印分析器的输出结果 |
%time statement |
报告statement的执行时间 |
%timeit statement |
多次执行statement以计算系综平均执行时间。对那些执行时 间非常小的代码很有用 |
%who、%who_ls、%whos |
显示interactive命名空间中定义的变量,信息级别/冗余度可变 |
%xdel variable |
删除variable,并尝试清除其在IPython中的对象上的一切引用 |
6. 输入和输出变量
输入文本被保存在名为_iX
的变量中,其中X是输入行的行号。每个输入变量都有一个对应的输出变量_X
。_iX
和_X
对应到IPython的In
和Out
变量中。
由于输入变量是字符串,因此可以用Python的exec
关键字重新执行
In [30]: exec _i27
有几个魔术命令可用于控制输入和输出历史。%hist用于打印全部或部分输入历史,可以选择是否带行号。%reset
用于清空interactive命名空间,并可选择是否清空输入和输出缓存。%xdel
用于从IPython系统中移除特定对象的一切引用。详细信息请参考相应魔术命令的文档。
7. 记录输入和输出
IPython能够记录整个控制台会话,包括输入和输出。执行%logstart
即可开始记录日志
In [29]: %logstart
Activating auto-logging. Current session state plus future input saved.
Filename : ipython_log.py
Mode : rotate
Output logging : False
Raw input log : False
Timestamping : False
State : active
相关魔术命令还有:%logoff
, %logon
, %logstate
, %logstop
8. 与操作系统交互
IPython跟操作系统结合紧密,可以直接在IPython中实现命令行活动。 与系统相关的IPython命令如下:
!cmd |
在系统shell中执行cmd |
output=!cmd args |
执行cmd,并将结果放在output中 |
%bookmark |
使用IPython的目录书签系统 |
%cd directory |
更改工作目录 |
%pwd |
返回系统当前工作目录 |
%env |
以字典形式返回系统环境变量 |
9. 目录书签系统
IPython的目录书签系统能够保存常用目录的别名以便实现快速跳转。书签能够持久化保存。
如:
%bookmark pys 'C:/User/xxx/PyWorkSpace'
定义好书签之后,就可以在执行魔术命令%cd时使用这些书签了:
cd pys
列出所有书签:
%bookmark -l
书签名与目录冲突
%bookmark -b pys
强制使用书签目录
10. 交互式调试器
IPython增强了pdb,如Tab键自动完成、语法高亮、为异常信息添加上下文参考等。
代码调试的最佳时机就是错误发生的时候,在发生异常之后马上输入 %debug
命令将会调用调试器,并直接跳转到引发异常的那个帧。
在pdb中,可以查看各个帧中的一切对象和数据。默认是从最低级开始的。输入u(p)
或d(own)
可以在栈的各级别之间切换。
使用 %pdb on
命令可以开启自动调试功能, 即当程序异常时直接开始进行调试。%pdb off
命令可关闭自动调试。如果不加参数,只输入%pdb
命令则在两种模式之间切换。
如果你想设置断点或对函数进行单步调试。 可以使用带有 -d 选项的%run
命令,这将会在执行脚本文件中的代码之前打开调试器。然后,如果你想套设置断点,那么使用 b(reak) x
命令,其中x为行号。前进一行使用 n(ext)
命令,进入函数体使用 s(tep into)
然后使用 c(ontinue)
命令即可直行至断点处。要查看变量可以使用 !x
,其中x
为变量名。
run -d ipython_bug.py
b 12
c
想要精通这个交互式调试器,必须经过大量的实践才行。如果你习惯了使用某款IDE刚开始使用这种终端型调试器可能会觉得有点麻烦,但慢慢就习惯了。虽然大部分IDE都拥有优秀的GUI调试器,但是在IPython中调试程序却往往会带来更高的生产率。
pdb主要命令如下:
h(elp) |
显示命令列表 |
help command |
显示命令的说明文档 |
c(continue) |
回复程序的执行 |
q(uit) |
退出调试器 |
b(reak) number |
在指定行设置断点 |
s(tep) |
单步进入(step into)函数 |
n(next) |
执行当前行(step over),并进入下一行 |
u(p)/d(own) |
在函数调用栈中向上或向下移动 |
a(rgs) |
显示当前函数的参数 |
debug statement |
在新的调试器中调用语句statement |
l(ist) statement |
显示当前行,以及当前栈级别上的上下文参考代码 |
w(here) |
打印当前位置的完整栈跟踪 |
11. 调试器的其他使用场景
除了上面提到的,还有另外的调试方法。可以使用set_trace
这个特别的函数。下面两个函数或许会对你很有用(你也可以像我一向直接将其添加到IPython配置中):
def set_trace():
from IPython.core.debugger import Pdb
Pdb(color_sheme='Linux').set_trace(sys._getframe().f_back)
def debug(f, *args, **kwargs):
from IPython.core.debugger import Pdb
pdb = Pdb(color_scheme='Linux')
return pdb.runcall(f, *args, **kwargs)
第一个函这set_trace
很简单,你可以将它放在代码中任何希望停下来查看一番的地方:
def calling_things():
set_trace() #自定义的调试函数
works_fine()
throws_an_exception()
第二个函数(debug),使你能够直接在任意函数上使用调试器。
假设我们有如下函数:
def f(x, y, z=1):
tmp = x + y
return tmp / z
现在想对其进行单步调试,按如下方式即可:
debug(f, 1, 2, z=3)
12. 基本性能分析: %prun
和%run -p
代码性能分析与代码执行时间分析的区别在于,它关注的是耗费时间的位置。
python使用cProfile模块进行性能分析,它会记录各函数所耗费的时间。
使用方法如下:
python -m cProfile cprof_example.py
执行之后会发现输出结果是按函数名排序的,这我们很难发现哪里才是最花时间的地方,一次通常会再加一个 -s 指定排序规则:
python -m cProfile -s cumulative cprof_example.py
除此自外,cProfile还能以编程的方式分析任意代码块的性能。IPython为此提供了一个方便的接口。即 %prun
和带 -p 命令的%run
。
%prun
格式跟cProfle相同,但它分析的是部分语句而不是整个文件。
%prun -l 7 -s cumulative run_experiment()
利用 %run -p 也能达到上面的系统命令的效果去无需退出IPython:
%run -p -s cumulative cprof_example.py
13. 逐行分析函数性能
有时从%prun
得到的信息要么不足以说明函数的执行时间,要么复杂到难以理解。这是我们可以使用一个叫做line_profiler的小型库(可以通过PyPI或其他包管理工具获取)。其中有一个新的魔术函数%lprun
,它可以对一个或多个函数进行逐行性能分析。
14. IPython HTML Notebook
IPython Notebook目前已成为一种非常棒的交互式计算工具,同时还是科研和教学的一种理想媒介。它有一种基于JSON的文档格式.ipynb,一种流行的演示手段就是使用IPython Notebook再将.ipynb文件发布到网上以供所有人查阅。
IPython Notebook是一个运行于命令行上的轻量级服务器进程。
由于我们是在一个Web浏览器上使用Notebook的,因此该服务器进程可以运行于任何其他地方。甚至可以连接到那些运行在云服务上的Notebook。
15. 重新加载模块依赖项
reload
重加载模块dreload
递归重加载模块
16. 个性化和配置
IPython shell在外观(如颜色、提示符、行间距)和行为方面的大部分内容都是可以配置的,如:
- 颜色方案
- 输入输出提示符
- 去掉Out提示符后的空行
- 执行任意的Python语句,你可以定制你希望每次启动IPython都发生的事
- 启动IPython扩展
- 自定义魔术命令或系统别名
- 所有的配置项都在一个叫做 ipython_config.py 的文件中,可以在%HOME%/.ipython/目录中找到。