IPython Sphinx 指令#

注意

这是从旧的 IPython wiki 直接复制过来的,目前正在开发中。开发指南的这一部分中的许多信息已经过时。

ipython 指令是一个用于嵌入 Sphinx 文档中的有状态 ipython shell。它了解标准的 ipython 提示符,并提取输入和输出行。这些提示符将从 1 开始重新编号。输入将被传递给嵌入的 ipython 解释器,并且该解释器的输出也将被插入。例如,如下代码块:

.. code:: python3

   In [136]: x = 2

   In [137]: x**3
   Out[137]: 8

将被渲染为

In [136]: x = 2

In [137]: x**3
Out[137]: 8

备注

本教程应与本文档的Sphinx源代码并排阅读,因为否则您将只能看到渲染后的输出,而看不到生成它的代码。除了上面的示例外,我们通常不会在本文档中展示生成渲染输出的字面ReST。

存储了来自先前会话的状态,并且捕获了标准错误。在文档构建时,ipython 的输出和标准错误将被插入,提示符将被重新编号。因此,下面的提示符应在渲染的文档中重新编号,并从上面的代码块结束处继续。

In [138]: z = x*3   # x is recalled from previous block

In [139]: z
Out[139]: 6

In [140]: print z
--------> print(z)
6

In [141]: q = z[)   # this is a syntax error -- we trap ipy exceptions
------------------------------------------------------------
   File "<ipython console>", line 1
     q = z[)   # this is a syntax error -- we trap ipy exceptions
     ^
SyntaxError: invalid syntax

嵌入式解释器支持一些有限的标记。例如,你可以在你的 ipython 会话中添加注释,这些注释会原样报告。有一些方便的“伪装饰器”可以让你 doctest 输出。输入被传递给嵌入的 ipython 会话,而 ipython 会话的输出则插入到你的文档中。如果文档中的输出与 ipython 会话中的输出在 doctest 断言上不匹配,将会产生一个错误。

In [1]: x = 'hello world'

# this will raise an error if the ipython output is different
@doctest
In [2]: x.upper()
Out[2]: 'HELLO WORLD'

# some readline features cannot be supported, so we allow
# "verbatim" blocks, which are dumped in verbatim except prompts
# are continuously numbered
@verbatim
In [3]: x.st<TAB>
x.startswith  x.strip

支持多行输入。

In [130]: url = 'http://ichart.finance.yahoo.com/table.csv?s=CROX\
   .....: &d=9&e=22&f=2009&g=d&a=1&br=8&c=2006&ignore=.csv'

In [131]: print url.split('&')
--------> print(url.split('&'))
['http://ichart.finance.yahoo.com/table.csv?s=CROX', 'd=9', 'e=22',

你也可以对多行输出进行文档测试。只是在 ipython 指令中使用非确定性输入(如随机数)时要小心,因为你的输入会通过一个实时解释器运行,所以如果你对随机输出进行文档测试,你会得到一个错误。在这里,我们为随机数生成器“播种”以获得确定性输出,并且我们抑制种子行,使其不会出现在渲染输出中。

In [133]: import numpy.random

@suppress
In [134]: numpy.random.seed(2358)

@doctest
In [135]: numpy.random.rand(10,2)
Out[135]:
array([[ 0.64524308,  0.59943846],
 [ 0.47102322,  0.8715456 ],
 [ 0.29370834,  0.74776844],
 [ 0.99539577,  0.1313423 ],
 [ 0.16250302,  0.21103583],
 [ 0.81626524,  0.1312433 ],
 [ 0.67338089,  0.72302393],
 [ 0.7566368 ,  0.07033696],
 [ 0.22591016,  0.77731835],
 [ 0.0072729 ,  0.34273127]])

另一个多行输入和输出的演示

In [106]: print x
--------> print(x)
jdh

In [109]: for i in range(10):
   .....:     print i
   .....:
   .....:
0
1
2
3
4
5
6
7
8
9

大多数“伪装饰器”可以用作 ipython 模式的选项。例如,要设置 matplotlib pylab 但抑制输出,您可以这样做。在使用 matplotlib use 指令时,它应该在导入 pylab 之前发生。这不会显示在渲染的文档中,但命令将在嵌入的解释器中执行,并且后续行号将递增以反映输入:

.. code:: python3

   In [144]: from pylab import *

   In [145]: ion()
In [144]: from pylab import *

In [145]: ion()

同样地,你可以设置 :doctest::verbatim: 来将这些设置应用于整个块。例如,

In [9]: cd mpl/examples/
/home/jdhunter/mpl/examples

In [10]: pwd
Out[10]: '/home/jdhunter/mpl/examples'


In [14]: cd mpl/examples/<TAB>
mpl/examples/animation/        mpl/examples/misc/
mpl/examples/api/              mpl/examples/mplot3d/
mpl/examples/axes_grid/        mpl/examples/pylab_examples/
mpl/examples/event_handling/   mpl/examples/widgets

In [14]: cd mpl/examples/widgets/
/home/msierig/mpl/examples/widgets

In [15]: !wc *
    2    12    77 README.txt
   40    97   884 buttons.py
   26    90   712 check_buttons.py
   19    52   416 cursor.py
  180   404  4882 menu.py
   16    45   337 multicursor.py
   36   106   916 radio_buttons.py
   48   226  2082 rectangle_selector.py
   43   118  1063 slider_demo.py
   40   124  1088 span_selector.py
  450  1274 12457 total

你可以创建一个或多个 pyplot 图,并使用 @savefig 装饰器插入它们。

@savefig plot_simple.png width=4in
In [151]: plot([1,2,3]);

# use a semicolon to suppress the output
@savefig hist_simple.png width=4in
In [151]: hist(np.random.randn(10000), 100);

在后续的会话中,我们可以用一些文本更新当前图形,然后重新保存

In [151]: ylabel('number')

In [152]: title('normal distribution')

@savefig hist_with_text.png width=4in
In [153]: grid(True)

你也可以在源代码中包含函数定义。

In [3]: def square(x):
   ...:     """
   ...:     An overcomplicated square function as an example.
   ...:     """
   ...:     if x < 0:
   ...:         x = abs(x)
   ...:     y = x * x
   ...:     return y
   ...:

然后在后续章节中调用它。

In [4]: square(3)
Out [4]: 9

In [5]: square(-2)
Out [5]: 4

编写纯Python代码#

纯Python代码通过可选参数 python 得到支持。在这种纯Python语法中,您不包含Python解释器的输出。以下标记:

.. code:: python

   foo = 'bar'
   print foo
   foo = 2
   foo**2

呈现为

foo = 'bar'
print foo
foo = 2
foo**2

我们甚至可以使用 savefig 装饰器从 Python 中绘图,同时,可以使用分号抑制输出。

@savefig plot_simple_python.png width=4in
plot([1,2,3]);

同样地,标准错误被插入

foo = 'bar'
foo[)

注释被处理,状态被保留

# comments are handled
print foo

如果你没有看到下一个代码块,那么选项是有效的。

ioff()
ion()

多行输入被处理。

line = 'Multi\
        line &\
        support &\
        works'
print line.split('&')

函数定义被正确解析

def square(x):
    """
    An overcomplicated square function as an example.
    """
    if x < 0:
        x = abs(x)
    y = x * x
    return y

并且在会话之间保持持久性

print square(3)
print square(-2)

几乎所有你可以用 ipython 代码做的事情,你都可以用一个简单的 python 脚本来完成。显然,使用 doctest 选项是没有意义的。

伪装饰器#

以下是支持的装饰器及其可选参数。一些装饰器可以作为整个块的选项(例如 verbatimsuppress),而另一些仅适用于紧随其后的行(例如 savefig)。

@抑制

执行 ipython 输入块,但抑制输入和输出块在渲染输出中显示。此外,可以作为 ..ipython 块的指令选项应用于整个块,使用 :suppress:

@verbatim

插入输入和输出块为逐字记录,但自动递增行号。在内部,解释器将被提供一个空字符串,因此这是一个保持行号一致的无操作。此外,可以作为指令选项应用于整个 ..ipython 块,使用 :verbatim:

@savefig OUTFILE [IMAGE_OPTIONS]

将图形保存到静态目录并插入文档中,可能将其绑定到一个minipage中,和/或将代码/图形标签/引用放入以关联代码和图形。接受参数传递给图像指令(scale*width*等可以作为关键字参数);详见 图像选项

@doctest

将粘贴到 ipython 块中的输出与文档构建时生成的输出进行比较,如果不匹配则引发错误。此外,可以作为指令选项应用于整个 ..ipython 块,使用 :doctest:

配置选项#

ipython_savefig_dir

保存图像的目录。这是相对于 Sphinx 源目录的。默认是 html_static_path

ipython_rgxin

用于表示 IPython 输入行开始的编译正则表达式。默认是 re.compile('In [(d+)]:s?(.*)s*')。你不需要更改这个。

ipython_rgxout

用于表示 IPython 输出行开始的编译正则表达式。默认是 re.compile('Out[(d+)]:s?(.*)s*')。你不需要更改这个。

ipython_promptin

在生成的 ReST 中表示 IPython 输入提示的字符串。默认值是 'In [%d]:'。这表示期望在提示中使用行号。

ipython_promptout

在生成的 ReST 中表示 IPython 提示的字符串。默认值是 'Out [%d]:'。这要求在提示中使用行号。