14.5. 输入输出历史

前面我们看到IPython shell能够让你获取到命令的历史,使用向上箭头或者向下箭头,或者等同的Ctrl-p/Ctrl-n快捷键。除此之外,在IPython shell和notebook中,还提供了一些方法可以获得前面命令的输出结果,或者字符串形式的命令本身。本节将讨论它们。

14.5.1. IPython的 InOut 对象

阅读到这里,作者认为你已经相当熟悉IPython的In [1]:/Out[1]:风格的提示符了。但是其实这些提示符并不是为了美观而采用的装饰符号:它们会给出你提示,让你可以获取之前的输入和输出。例如你启动了一个IPython会话:

In [1]: import math

In [2]: math.sin(2)
Out[2]: 0.9092974268256817

In [3]: math.cos(2)
Out[3]: -0.4161468365471424

我们载入了內建的math包,然后计算了2的正弦和余弦值。这些输入和输出在IPython shell当中使用In/Out标签打印在屏幕上,但实际上这些标签的作用不限于此,IPython创建了两个Python的变量名叫InOut,在每次输入输出的情况下都会自动更新和相应:

In [4]: print(In)
['', 'import math', 'math.sin(2)', 'math.cos(2)', 'print(In)']

In [5]: Out
Out[5]: {2: 0.9092974268256817, 3: -0.4161468365471424}

In对象是一个列表,保存着本次IPython会话的所有输入命令(列表中的第一个元素是一个占位符,因此第一条命令是In[1]):

In [6]: print(In[1])
import math

Out对象是一个字典值,将输入的编号对应到它们相应的输出上面:

In [7]: print(Out[2])
0.9092974268256817

注意并不是所有的操作都有输出:例如,importprint语句就不会影响输出内容。然后再深入思考一下,你会发现,print是一个返回值为None的函数;简而言之,任何指令返回None都不会加入到Out当中。

当你需要用到历史结果时,上面的变量就非常有用。例如,我们检查一下sin(2) ** 2加上cos(2) ** 2的和,可以使用前面的结果:

In [8]: Out[2] ** 2 + Out[3] ** 2
Out[8]: 1.0

结果是1.0,和我们了解的三角函数运算得到的一样。在这个例子中,使用历史结果并不是特别需要,但是当你前面进行了非常耗时的运算的时候,重用这个结果是非常方便的。

14.5.2. 下划线变量和之前的输出

标准的Python shell包含着一个简单的快捷变量用来获取前一个输出结果;变量_(一个下划线),这个变量会更新为每次前一条语句的输出结果。IPython中也是可以使用的:

In [9]: print(_)
1.0

IPython扩展了这个功能,你可以使用双下划线获取倒数第二个输出结果,使用三下划线获取倒数第三个输出结果(当然会跳过无输出的命令):

In [10]: print(__)
-0.4161468365471424

In [11]: print(___)
0.9092974268256817

三个就打住了,IPython也不支持更多的下划线了,因为多于三个的下划线就变得比较难以数清楚了,在这种情况下,使用输入序号会更加方便一些。

这里还有一个快捷方式需要介绍,Out[x]的快捷写法是_x(一个下划线后面跟着输入序号):

In [12]: Out[2]
Out[12]: 0.9092974268256817

In [13]: _2
Out[13]: 0.9092974268256817

14.5.3. 取消输出

有时你可能希望取消一个语句的输出结果(这在我们使用绘图指令时很常见,我们会在Matplotlib简介中详细讨论)。或者你在执行的指令会产生的结果,你并不希望结果被存储在输出历史中,这样的结果就能在其他引用被移除后自动释放资源。取消一个指令的输出结果最简单的方法就是在语句最后加上一个分号:

In [14]: math.sin(2) + math.cos(2);

这里结果将会静默的计算出来,输出既不会打印在屏幕上,也不会保存在输出Out的字典中:

In [15]: 14 in Out
Out[15]: False

14.5.4. 相关的魔术命令

要想一次性获得批量的输入历史,%history魔术命令是非常有用的。下面例子展示了如何使用它打印出输入历史中头四个指令:

In [16]: %history -n 1-4
   1: import math
   2: math.sin(2)
   3: math.cos(2)
   4: print(In)

当然,你也可以使用%history?来查阅该魔术命令的文档。其他类似的魔术命令包括%rerun(重新执行输入历史中的某部分指令)和%save(将输入历史中的某部分内容保存成文件)。需要更多的信息,推荐使用?魔术符号来查阅文档,有关?号的内容请参见IPython帮助和文档