Ipython!

前几天偶然在公司内网上拖了一本 Learning IPython for Interactive Computing and Data Visualizatio,如名字所说,这本书主体内容就是讨论ipython的使用与数据的可视化。由于很薄,昨天为了打发时间就随便翻了翻,阅读完了前三章,认识到一个问题:我从来没有真正使用过ipython —- 之前只是很单纯地把ipython看作一个支持自动补全和缩进的交互shell,直到真正阅读了ipython的文档,才发现这样的认知相当无礼。

这篇笔记基本是以上文所提及到的书前两章和官方文案为主要参考资料,如果希望更深入学习,请务必参看。官方文案附于此:文档,书的话,我没有搜索过,不过应该是有pdf版本流于网上的,如果实在找不到的话,我也可以上传一份。

本文不会涉及到安装步骤,并且也假设读者理解特定术语(比如内省,profile)的意义。

初步

一旦您进入了ipython,ipython会提示您键入下面四个命令之一去试着使用ipython:

命令名说明
?ipython特性的介绍和概述
%quickref 一份手册,包含了所有的命令
helppython的帮助系统
object?关于object的详细信息,如果键入object??会更详细

Ok,我们从这里开始,当然,首先是推荐您看一下quickref的。您注意到了,这个命令以%开头。所有以%开头的方法,都是所谓的魔术方法(Magic function),也就是ipython内置的一些方法。需要注意的是,魔术方法有%和%%之分,比如%timeit%%timeit。这玩意在ipython中有专门的叫法,前者叫line magic后者叫cell magic。顾名思义,前者是专门针对一行的命令,后者针对多行的命令(这是notebook中的术语,关于notebook请参阅最后),如是而已。

所有的魔术方法都可以查看源码,仔细阅读的话,对自己写代码也很有裨益,具体方法是在魔术方法后面加??,譬如%timeit??。代码是经过高亮和格式化的,应该很容易阅读才是。如果您有着奇妙的好奇心的话,想必刚才也尝试过%timeit?。区别是,这次没有源码出现对吧。但是其他信息,比如type什么的指导性内容会显示出来。

魔术方法会在下文专门一节来讨论,这里有个印象即可。

接下来说说?

?其实上面已经有所涉及,总之您知道了可以用?修饰魔术方法获取更详细的信息。但是不只是这样,?其实是可以修饰python所有的对象。考虑到python中一切都是对象,所以您知道了,?事实上可以查看一切的变量(这里强调了是变量了,所以 1? 这样为什么会报错……恩哼?)。

尝试一下输入下面的代码,您会有更深入的了解。

In [1]: a = [1,2,3,4]
In [2]: a?
In [3]: list?
In [4]: import os
In [5]: os?
In [6]: os.open?
In [7]: super?

以上分别代表了变量,类,包,类中方法,内置函数,如您所见,均工作良好。把?替换为??,一般来说会得到更详尽的信息,,不过?通常就够了(对我而言)。另外,?其实作为前缀和作为后缀效果是相同的,只不过我更习惯放在后面而已。

上面的内容就是ipython最基础的部分,请务必熟悉。

魔术方法

ipython一个很(最)重要特性就是魔术方法,不过内置的魔术方法实在太多了点(试试使用%lsmagic看所有的魔术方法),这篇笔记当然不可能详述所有的魔术方法,这里会挑一些常用的来说,权作抛砖引玉。

pwd

如果您仔细看过前文,您会发现这个命令没有%,但是这个确实也是一个魔术方法,原因是,其实pwd这个命令只是一个链接,指向的是%pwd方法,%pwd指向系统的命令。当然这个命令含义很明显,就是打印当前路径。ipython把一些linux下常用的bash命令做了类似的处理,使用起来相当方便。我试了一下,大致有pwd,cd,whos,history,rm,ll,ls,mv,cp,alias,mkdir

!xxx

ipython虽然对不少常用命令做了封装,但是毕竟不会很多,比如突然希望执行vim或者top之类的linux命令,难道还需要切出去不成?其实不需要,因为ipython提供了一个额外的!语法去直接执行linux命令。比如,我需要执行top命令,那么在ipython中,只要这么写就好!top

更复杂的linux命令也是支持的,事实上,只要加上!,您完全可以把ipython当作bash来用。

而且,还可以赋值,比如这样:

files = !ls -1 -S | grep hello

%edit

编辑器在ipython下使用得如此频繁,以至于ipython专门有一个%edit方法。

不过默认效果估计会让您失望,因为没有指定的话,linux下默认会使用vi当作编辑器,windows下是notepad++(似乎?)。如果希望%edit打开自己喜爱的编辑器的话,需要在PATH中增加EDITOR项。

%run

ipython一般的使用,通常只是为了测试一行或者几行代码是否能够执行。究其原因,还是因为命令行中书写长代码相较于在文件中写代码并不方便,一方面是格式,另一方面是在命令行中写代码,一旦中间代码写错,修改起来还是很麻烦的。于是我们不得不一次次退出ipython,去python xxx.py执行。或者tmux开两个窗口来测试。

但是其实ipython已经提供了很方便的机制用来执行一个脚本,就是%run命令,%run可以简化为run。

使用起来类似于熟悉的python test.py,使用run test.py就好。run命令还可以附加选项,常用的有-t选项,这个会在脚本执行完后,打印出执行的cpu timings。如果指定了-t选项,后面可以跟一个-Nx,x代表一个数字。表示重复执行x次。

另外比较好用的是-d选项,这个会在pdb中运行脚本。后跟-bxx打断点。个人没有什么python调试的经验,您有兴趣可以亲自尝试。

还有一个-p选项,这个选项会开启python profiler,从而打印出详细的执行时间、函数调用等等信息供优化参考。

%timeit

这个命令用来测试一条命令执行的时间,一般而且,会重复100次运行这个命令,然后取出最好的3个结果取平均值。

试着执行下面的命令:

In[1]: %timeit [x*x for x in range(100000)]

同样,可以指定选项。

-n指定重复次数,默认100

-r是取多少个结果的平均值,默认是3

顺带一提,%timeit测出来的结果远比真实运行更快,原因是,timeit执行中,会暂时关闭掉垃圾回收(gc)。

shell中使用python变量

其实这个不算是魔术方法啦,只是单独列出来也不太合适,所以也就写在这里。

请看下面这段代码:

folder = 'data'
mkdir $folder
cd %folder

注意到了么,mkdir是一个魔术方法,它是%mkdir的一个链接,%mkdir事实上就是shell中的mkdir方法。而folder是一个python变量。但是,确实,shell下的命令访问了python的变量,只是在变量名前面加了$。如果您熟悉shell脚本的话,这种方式应该很亲切才对。

%bookmark

这个方法通常用来记忆路径,譬如说,您每次都需要cd进一个叫做github/miko/loli/shoujo的目录,这时候,您可以对这个路径做一个书签,%bookmark shoujo github/miko/loli/shoujo,这样以后就可以直接cd shoujo这样。

顺便,如果没有指定路径,会默认使用当前路径。

%alias

正如名字揭示的,这个方法用来指定别名。不过,ipython的%alias还能进行参数传递。

看看下面这段:

In [1]: %alias largest ls -1sSh | grep %s
In [2]: largest circles

很容易懂不是么?%alias后面跟的那个参数就是别名,然后可以通过%s来指定一个参数,使用时传入。

%store

默认的,别名只会存在于本次会话中,如果希望下次还能使用这个别名,使用%store方法存下来吧。%store latest

另外,没保存也不要紧,%store -r会恢复上次会话的别名。

%hist

ipython中history会保存所有会话中的记录,嘛,所以隔一年什么的记录就会相当多啦。

虽然我知道你们都会用up,down来寻找历史记录……恩,试试ctrl+r,有惊喜。

另外,类似于hist 3-7什么的,好像也不用我解释就是了。

-g选项和grep类似,可以查找些东西出来,然后-n显示行号,-f保存历史记录到文件中去,-p把行号显示为n:>>>-n把输入的结果显示出来(我猜没多少用这些个……

内省

最开始就解释过???了,如果对python比较熟悉的话,会意识到这其实就是内省。

后面这里有几个大概不会用到的方法……

%psource,%pfile,%pdoc,%pdef

其实就是把?的结果进行了摘录……额,有人会用么?

notebook

ipython中最让人惊艳(我觉得)的就是这个notebook功能,不过要启用这个,首先需要安装pyZMQ。然后执行ipython notebook,嘿,您看见了什么。一个基于web的ipython shell!

notebook实际上会在本地的8888端口开一个服务器(tornado),您所见到的首页,通常叫做notebook dashboard,它会列出所有的notebook。

每个notebook文件都是一个叫做.ipynb的扩展文件格式,这是一个包含了json的文件。

文件包含了从交互会话中取得的输入输出,然后还有一些metadata以供ipython使用。

notebook中的代码片段有个专门的术语叫做cell,这里事先说明。

notebook使用起来和ipython差不多,不过修改起来方便得多,并且可以建多个notebook,所以使用起来各种方便。不过,需要联网的库应该是用不了的,我测试requests没有成功……

执行一个cell使用ctrl+Enter,执行并新建一个新的notebook使用shift+enter,当然您去戳上面的按钮也是可以的。

您可以通过键入ctrl+M 然后 H来得知有那些键盘快捷键可以使用。

cell中当然也可以使用魔术方法,而且,由于notebook独特的优势,您可能需要测试多行代码,这时候,请别忘记用%%代替%

cell中有一个特殊的%%file方法,可以创建一个文件,具体使用是这样:

%%file nyanya.txt
hello world
this is nyanya
over

很简单不是么。

然后还有一个%%!方法。这个方法可以执行一些bash命令。

最后,notebook还可以充当一个markdown编辑器……

finally

上面关于ipython已经说得足够多了,如果您认真阅读过,相信您也会惊讶:原来ipython能做到这么多事!如果能让您产生这样的想法,那就是我的荣幸。

不过毕竟只有这么多字,其实讨论得还是不够,更多的,您恐怕要在实际使用中才能知道一些漂亮的用法并且会记忆住更多的魔术方法。

但是您会慢慢熟练起来,并爱上它的,我相信。

谢谢您的阅读。

以上。

去过动漫展并被坑得不轻躺在床上不想起来的AS。