使用Sphinx描述代码¶
在 previous sections of the tutorial 您可以阅读如何在Sphinx中编写叙事或散文文档。在本节中,您将改为描述代码对象。
Sphinx支持用几种语言来记录代码对象,即,Python、C、C++、JavaScript和reStructredText。其中的每一个都可以使用一系列指令和角色进行记录,这些指令和角色按 domain 。在本教程的其余部分中,您将使用Python域,但本节中看到的所有概念也适用于其他域。
Python¶
记录Python对象¶
Sphinx提供了几个角色和指令来记录Python对象,所有这些对象都集中在 the Python domain 。例如,您可以使用 py:function
指令来记录一个Python函数,如下所示:
Creating recipes
----------------
To retrieve a list of random ingredients,
you can use the ``lumache.get_random_ingredients()`` function:
.. py:function:: lumache.get_random_ingredients(kind=None)
Return a list of random ingredients as strings.
:param kind: Optional "kind" of ingredients.
:type kind: list[str] or None
:return: The ingredients list.
:rtype: list[str]
其渲染方式如下所示:

在Sphinx中记录Python函数的呈现结果¶
请注意以下几点:
Sphinx解析了
.. py:function
指令,并相应地突出显示模块、函数名和参数。指令内容包括对该函数的一行描述,以及 info field list 包含函数参数、其预期类型、返回值和返回类型。
备注
这个 py:
前缀指定 domain 。您可以配置默认域,以便可以省略前缀,或者全局使用 primary_domain
配置,或使用 default-domain
指令将其从被调用的位置更改到文件的末尾。例如,如果将其设置为 py
(默认设置),您可以编写 .. function::
直接去吧。
交叉引用Python对象¶
默认情况下,这些指令中的大多数生成可以从文档的任何部分交叉引用的实体 a corresponding role 。对于函数,您可以使用 py:func
为此,如下所示:
The ``kind`` parameter should be either ``"meat"``, ``"fish"``,
or ``"veggies"``. Otherwise, :py:func:`lumache.get_random_ingredients`
will raise an exception.
在生成代码文档时,Sphinx将只使用对象的名称自动生成交叉引用,而不必显式使用角色。属性来描述函数引发的自定义异常。 py:exception
指令:
.. py:exception:: lumache.InvalidKindError
Raised if the kind is invalid.
然后,将此例外添加到函数的原始描述中:
.. py:function:: lumache.get_random_ingredients(kind=None)
Return a list of random ingredients as strings.
:param kind: Optional "kind" of ingredients.
:type kind: list[str] or None
:raise lumache.InvalidKindError: If the kind is invalid.
:return: The ingredients list.
:rtype: list[str]
最后,结果是这样的:

使用交叉引用在Sphinx中记录Python函数的HTML结果¶
很漂亮,不是吗?
在您的文档中包含文档测试¶
由于您现在描述的是来自Python库的代码,因此尽可能保持文档和代码的同步将变得非常有用。在Sphinx中实现这一点的方法之一是在文档中包含代码片段,称为 doctests ,在构建文档时执行。
要演示本教程中介绍的doctest和其他Sphinx特性,Sphinx需要能够导入代码。要做到这一点,请在下面的开头写下 conf.py
:
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here.
import pathlib
import sys
sys.path.insert(0, pathlib.Path(__file__).parents[2].resolve().as_posix())
备注
一种替代更改 sys.path
变量的目的是创建一个 pyproject.toml
文件,并使代码可安装,这样它的行为就像任何其他的Python库一样。然而, sys.path
方法更简单。
然后,在向文档中添加文档测试之前,启用 doctest 分机入 conf.py
:
extensions = [
'sphinx.ext.duration',
'sphinx.ext.doctest',
]
接下来,编写一个doctest块,如下所示:
>>> import lumache
>>> lumache.get_random_ingredients()
['shells', 'gorgonzola', 'parsley']
Doctest包括要运行的Python指令,前面有 >>>
标准的Python解释器提示符,以及每条指令的预期输出。通过这种方式,Sphinx可以检查实际输出是否与预期输出匹配。
为了观察doctest失败是什么样子(而不是上面的代码错误),让我们首先不正确地编写返回值。因此,添加一个函数 get_random_ingredients
如下所示:
def get_random_ingredients(kind=None):
return ["eggs", "bacon", "spam"]
您现在可以运行 make doctest
来执行文档的文档测试。最初,这将显示一个错误,因为实际代码的行为与指定的不同:
(.venv) $ make doctest
Running Sphinx v4.2.0
loading pickled environment... done
...
running tests...
Document: usage
---------------
**********************************************************************
File "usage.rst", line 44, in default
Failed example:
lumache.get_random_ingredients()
Expected:
['shells', 'gorgonzola', 'parsley']
Got:
['eggs', 'bacon', 'spam']
**********************************************************************
...
make: *** [Makefile:20: doctest] Error 1
如您所见,doctest报告了预期结果和实际结果,以便于检查。现在是修复函数的时候了:
def get_random_ingredients(kind=None):
return ["shells", "gorgonzola", "parsley"]
最后, make doctest
报告成功!
然而,对于大型项目,这种手动方法可能会变得有点单调乏味。在下一节中,您将看到 how to automate the process 。
其他语言(C、C++等)¶
记录和交叉引用对象¶
Sphinx还支持记录和交叉引用用其他编程语言编写的对象。还有四个额外的内置域:C、C++、JavaScript和reStructiredText。第三方扩展可以为更多语言定义域,例如
Fortran <https://sphinx-fortran.readthedocs.io> _,
Julia <https://bastikr.github.io/sphinx-julia> _,或
PHP <https://github.com/markstory/sphinxcontrib-phpdomain> _.
例如,要记录C++类型定义,可以使用内置的 cpp:type
指令,如下所示:
.. cpp:type:: std::vector<int> CustomList
A typedef-like declaration of a type.
这将产生以下结果:
-
typedef std::vector<int> CustomList¶
一个类型的类typlef声明。
然后,所有此类指令都会生成可通过使用相应角色进行交叉引用的引用。例如,若要引用上一个类型定义,可以使用 cpp:type
角色如下:
Cross reference to :cpp:type:`CustomList`.
这将产生指向前一个定义的超链接: CustomList
。