sphinx - python文档生成器

  |  

Sphinx

Sphinx 是一个python第三方库,它将一组纯文本源文件转换为各种输出格式的工具,自动生成交叉引用、索引等,也就是说,如果您有一个包含 reStructuredText 或 Markdown 的源代码注释等,Sphinx可以生成一系列HTML文件、PDF文件(通过LaTeX)、手册页等等。

Sphinx专注于文档,特别是手写文档,然而,Sphinx也可以用来生成博客、主页甚至书籍。Sphinx的大部分功能来自其默认纯文本标记格式(reStructuredText)的丰富性。

安装

首先我们先安装它,使用pip安装

1
pip install sphinx

安装之后可以替换主题,如果你有一个特定的主题,你可以使用pip安装它,例如,我们使用sphinx_rtd_theme主题,主题会主动安装sphinx,所以如果我们直接安装主题,上一步的安装可以省略。

1
$ pip install sphinx_rtd_theme

安装完成后可以使用命令sphinx-build查看版本

1
2
$ sphinx-build --version
sphinx-build 6.2.1

设置文档源

Sphinx纯文本文档源集合的根目录称为 source directory . 此目录还包含sphinx配置文件 conf.py ,在这里您可以配置Sphinx如何读取源代码和构建文档的所有方面。

Sphinx有一个命令叫 sphinx-quickstart 设置源目录并创建默认 conf.py 从几个问题中配置最有用的配置值。

1
sphinx-quickstart docs

以下是我创建的时候的信息,其中 > 表示输入,[] 表示默认值。这里可以根据需要进行设置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ sphinx-quickstart docs
欢迎使用 Sphinx 6.2.1 快速配置工具。

请输入接下来各项设定的值(如果方括号中指定了默认值,直接
按回车即可使用默认值)。

已选择根路径:docs

有两种方式来设置用于放置 Sphinx 输出的构建目录:
一是在根路径下创建“_build”目录,二是在根路径下创建“source
和“build”两个独立的目录。
> 独立的源文件和构建目录(y/n) [n]: y

项目名称将会出现在文档的许多地方。
> 项目名称: Lumache
> 作者名称: aaron
> 项目发行版本 []: 1.0

如果用英语以外的语言编写文档,
你可以在此按语言代码选择语种。
Sphinx 会把内置文本翻译成相应语言的版本。

支持的语言代码列表见:
https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language。
> 项目语种 [en]:

正在创建文件 /home/aaron/projects/PycharmProjects/TheM78Nebula/docs/source/conf.py。
正在创建文件 /home/aaron/projects/PycharmProjects/TheM78Nebula/docs/source/index.rst。
正在创建文件 /home/aaron/projects/PycharmProjects/TheM78Nebula/docs/Makefile。
正在创建文件 /home/aaron/projects/PycharmProjects/TheM78Nebula/docs/make.bat。

完成:已创建初始目录结构。

你现在可以填写主文档文件 /home/aaron/projects/PycharmProjects/TheM78Nebula/docs/source/index.rst 然后创建其他文档源文件了。 像这样用 Makefile 构建文档:
  make builder
此处的“builder”代指支持的构建器名称,比如 html、latex 或 linkcheck。

全部完成之后,我们可以看到docs目录下的文件结构如下:

1
2
3
4
5
6
7
8
9
docs
├── build
├── make.bat
├── Makefile
└── source
├── conf.py
├── index.rst
├── _static
└── _templates

这些文件中的每个文件的目的是:

  • build/ 一个空目录(目前),它将保存呈现的文档。
  • make.bat and Makefile 方便的脚本可以简化一些常见的Sphinx操作,比如呈现内容。
  • source/conf.py 保存Sphinx项目配置的一个Python脚本。它包含您为指定的项目名称和版本 sphinx-quickstart ,以及一些额外的配置密钥。
  • source/index.rst 这个 root document 作为欢迎页面,并包含“目录树”的根(或 toctree )。

现在运行以下命令,这样我们就可以得到一个空白的HTML文档了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ sphinx-build -b html docs/source/ docs/build/html
正在运行 Sphinx v6.2.1
正在创建输出目录... 完成
正在构建 [mo]: 0 个 po 文件的目标文件已过期
正在写入输出……
正在构建 [html]: 1 个源文件的目标文件已过期
正在更新环境:[新配置] 有 1 个新增文件,有 0 个文件已被修改,有 0 个文件已被移除
正在读取源文件……[100%] index
正在查找当前已过期的文件……没有找到已过期文件
正在 Pickle 序列化环境... 完成
正在校验一致性... 完成
正在准备写入文档... 完成
正在写入输出……[100%] index
正在生成索引... genindex 完成
正在写入附加页面... search 完成
正在复制静态文件... 完成
正在复制额外文件... 完成
正在导出 English (code: en) 的搜索索引... 完成
正在导出对象清单... 完成
构建成功。

HTML 页面保存在 docs/build/html 目录。

然后在浏览器中打开 docs/build/html/index.html ,你就可以看到一个简单的欢迎页面了。

sphinx简单欢迎页

构建文档

这里显示的首页就是docs/source/index.rst中的内容,我们可以在这里添加一些内容,然后重新构建文档。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.. Lumache documentation master file, created by
sphinx-quickstart on Mon May 22 23:33:09 2023.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.

Welcome to Lumache's documentation!
===================================

.. toctree::
:maxdepth: 2
:caption: Contents:


**Lumache** (/lu'make/) is a Python library for cooks and food lovers that
creates recipes mixing random ingredients. It pulls data from the `Open Food
Facts database <https://world.openfoodfacts.org/>`_ and offers a *simple* and
*intuitive* API.

.. note::

This project is under active development.


Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

它展示了reStrutiredText语法的几个功能,包括:

- 使用 === 标记了一个标题
- 以下两个示例的内联标记:**strong emphasis** (通常为粗体)和 *emphasis* (通常为斜体)
- 一个行内的链接 (用于链接到 Open Food Facts)
- 一个 note 提示

现在,要使用新内容,可以使用刚才用过的 sphinx-build 命令,或者按如下方式利用make脚本生成,注意,这种方式需要系统中安装有make程序:、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ cd docs
$ make html
正在运行 Sphinx v6.2.1
正在构建 [mo]: 0 个 po 文件的目标文件已过期
正在写入输出……
正在构建 [html]: 1 个源文件的目标文件已过期
正在更新环境:[新配置] 有 1 个新增文件,有 0 个文件已被修改,有 0 个文件已被移除
正在读取源文件……[100%] index
正在查找当前已过期的文件……没有找到已过期文件
正在 Pickle 序列化环境... 完成
正在校验一致性... 完成
正在准备写入文档... 完成
正在写入输出……[100%] index
正在生成索引... genindex 完成
正在写入附加页面... search 完成
正在复制静态文件... 完成
正在复制额外文件... 完成
正在导出 English (code: en) 的搜索索引... 完成
正在导出对象清单... 完成
构建成功。

HTML 页面保存在 build/html 目录。

运行完成之后,再次打开docs/build/html/index.html,你就可以看到新的内容了。

欢迎页新内容

当然,sphinx还支持其他的文档格式,比如PDF,ePub等,这里就不再赘述了。

1
2
# epub 格式生成方式
$ make epub

定制

sphinx还有很多内置的扩展来定制化功能。

内置扩展

比如我们找到 docs/source/conf.py 添加一个扩展,这个扩展可以显示页面集成的时间。

1
2
3
4
5
6
7
8
# docs/source/conf.py

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.duration',
]

添加扩展之后,就能在控制台输出的末尾看到页面生成的时间了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ make html
正在运行 Sphinx v6.2.1
正在加载 Pickle 序列化的环境... 完成
正在构建 [mo]: 0 个 po 文件的目标文件已过期
正在写入输出……
正在构建 [html]: 0 个源文件的目标文件已过期
正在更新环境:[扩展发生了变化 ('sphinx.ext.duration')] 有 1 个新增文件,有 0 个文件已被修改,有 0 个文件已被移除
正在读取源文件……[100%] index
正在查找当前已过期的文件……没有找到已过期文件
正在 Pickle 序列化环境... 完成
正在校验一致性... 完成
正在准备写入文档... 完成
正在写入输出……[100%] index
正在生成索引... genindex 完成
正在写入附加页面... search 完成
正在复制静态文件... 完成
正在复制额外文件... 完成
正在导出 English (code: en) 的搜索索引... 完成
正在导出对象清单... 完成

====================== 最长读取耗时 =======================
0.030 index
构建成功。

HTML 页面保存在 build/html 目录。

主题

还记得我们在刚开始创建项目的时候,我们安装一个第三方的主题吗?这里我们可以修改 conf.py 来更换主题。

1
2
3
4
# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'

更改后,我们重新生成页面,就能看到新的主题了。

!(new theme)[/post/sphinx/new-theme.png]

叙事性文档

跨多页组织文档

终于开始写文档了,我们可以在 docs/source 目录下创建一个新的文件,比如 usage.rst ,然后在 index.rst 中添加一个链接到这个文件。

首先编写 usage.rst 文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
Usage
=====

Installation
------------

To use Lumache, first install it using pip:

.. code-block:: console

(.venv) $ pip install lumache

这个新文件包含两个 section 页眉、普通段落文本和 code-block 指令

code-block 指令将内容块呈现为源代码,并使用适当的语法突出显示(在本例中为泛型 console 文本)。

文档的结构由一系列标题样式决定,这意味着通过使用 — 的 “Installation” 以及之后的部分,对于使用 === 的 “Usage” 部分,您已经将 “Installation” 声明为 subsection “用法”的概念。

要为了完成显示,您还需要在 index.rst 添加一个 usage.rst 的链接,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Welcome to Lumache's documentation!
===================================

.. toctree::
:maxdepth: 2
:caption: Contents:

usage

**Lumache** (/lu'make/) is a Python library for cooks and food lovers that
creates recipes mixing random ingredients. It pulls data from the `Open Food
Facts database <https://world.openfoodfacts.org/>`_ and offers a *simple* and
*intuitive* API.

.. note::

This project is under active development.


Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

更新页面,就能看到新的内容了。

警告

外部文档 toctree 将导致 WARNING: document isn’t included in any toctree 消息,并且用户将无法访问。

跨多页组织链接01

跨多页组织链接02

添加交叉引用

Sphinx的一个强大功能是能够无缝地添加 cross-references 文档的特定部分:文档、章节、图形、代码对象等。

要添加交叉引用,请将这句话添加到 index.rst 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.. Lumache documentation master file, created by
sphinx-quickstart on Mon May 22 23:33:09 2023.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.

Welcome to Lumache's documentation!
===================================

.. toctree::
:maxdepth: 2
:caption: Contents:

usage

Check out the :doc:`usage` section for further information.

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

这个 doc 会自动引用项目中的特定文档,在本例中为 usage.rst 。

当然也可以添加对项目任意部分的交叉引用。为此,需要使用 ref 角色,并添加显式 label ,它的作用就是 a target 。

例如,修改 usage.rst 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
Usage
=====

.. _installation:

Installation
------------

To use Lumache, first install it using pip:

.. code-block:: console

(.venv) $ pip install lumache

并且将 label 添加到 index.rst 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.. Lumache documentation master file, created by
sphinx-quickstart on Mon May 22 23:33:09 2023.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.

Welcome to Lumache's documentation!
===================================

.. toctree::
:maxdepth: 2
:caption: Contents:

usage

Check out the :doc:`usage` section for further information, including how to
:ref:`install <installation>` the project.

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

重新生成页面,就能看到新的内容了。

使用Sphinx描述代码

记录Python对象

Sphinx提供了几个角色和指令来记录Python对象,所有这些对象都集中在 the Python domain 。例如,可以使用 py:function 指令来记录一个Python函数,这里我们修改usage.rst,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Usage
=====

.. _installation:

Installation
------------

To use Lumache, first install it using pip:

.. code-block:: console

(.venv) $ pip install lumache

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]

python对象描述

请注意以下几点:

  • Sphinx解析了 .. py:function 指令,并相应地突出显示模块、函数名和参数。
  • 指令内容包括对该函数的一行描述,以及 info field list 包含函数参数、其预期类型、返回值和返回类型。

备注

这个 py: 前缀指定 domain 。您可以配置默认域,以便可以省略前缀,或者全局使用 primary_domain 配置,或使用 default-domain 指令将其从被调用的位置更改到文件的末尾。例如,如果将其设置为 py (默认设置),您可以编写 .. function:: 直接去吧。

交叉引用Python对象

默认情况下,这些指令中的大多数生成可以从文档的任何部分交叉引用的实体 (a corresponding role)[https://www.osgeo.cn/sphinx/usage/restructuredtext/domains.html#python-roles] 。对于函数,可以使用 py:func,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Usage
=====

.. _installation:

Installation
------------

To use Lumache, first install it using pip:

.. code-block:: console

(.venv) $ pip install lumache

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]

The ``kind`` parameter should be either ``"meat"``, ``"fish"``,
or ``"veggies"``. Otherwise, :py:func:`lumache.get_random_ingredients`
will raise an exception.

在生成代码文档时,Sphinx只使用对象的名称自动生成交叉引用,而不必显式使用角色,页面表现为一个链接跳转。

我们也可以使用属性来描述函数引发的自定义异常,比如py:exception 指令:

首先定义一个异常:

1
2
3
.. py:exception:: lumache.InvalidKindError

Raised if the kind is invalid.

然后在函数的原始描述中引用:

1
2
3
4
5
6
7
8
9
.. 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]

usage.rst 完整内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Usage
=====

.. _installation:

Installation
------------

To use Lumache, first install it using pip:

.. code-block:: console

(.venv) $ pip install lumache

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
:raise lumache.InvalidKindError: If the kind is invalid.
:return: The ingredients list.
:rtype: list[str]

.. py:exception:: lumache.InvalidKindError

Raised if the kind is invalid.

The ``kind`` parameter should be either ``"meat"``, ``"fish"``,
or ``"veggies"``. Otherwise, :py:func:`lumache.get_random_ingredients`
will raise an exception.

重新更新页面,等待构建完成,就可以看到新的效果了,效果如下所示。

python异常描述

文档测试

Sphinx 不仅提供了一种在文档中编写代码示例的方法,还提供了在文档中编写测试的方法。

这些测试可以在构建文档时运行,以确保文档中的示例代码仍然有效。这些测试称为文档测试,它们使用 doctest 模块。

对于代码描述和正常的代码实现逻辑保持一致是很重要的。在Sphinx中实现这一点的方法之一是在文档中包含代码片段,称为 doctests ,在构建文档时执行。

要显示这个功能,需要 Sphinx 需要能够导入代码。为了要做到这一点,请在 conf.py 中头部添加:

1
2
3
4
5
# 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 中,这样就可以将项目根目录添加到 python 的查找路径,以便在 Sphinx 中执行 Python 命令可以导入项目中的任何模块。

备注

一种替代更改 sys.path 变量的目的是创建一个 pyproject.toml 文件,并使代码可安装,这样它的行为就像任何其他的Python库一样。然而, sys.path 方法更简单。

然后,再启用 doctest 功能,需要在 conf.py 中添加扩展:

1
2
3
4
extensions = [
'sphinx.ext.duration',
'sphinx.ext.doctest',
]

整体的 conf.py 文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ cat source/conf.py
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# 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())

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = 'Lumache'
copyright = '2023, aaron'
author = 'aaron'
release = '1.0'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = [
'sphinx.ext.duration',
'sphinx.ext.doctest',
]

templates_path = ['_templates']
exclude_patterns = []



# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']

在 source/usage.rst 文件中添加一个 doctest 块,如下所示:

1
2
3
>>> import lumache
>>> lumache.get_random_ingredients()
['shells', 'gorgonzola', 'parsley']

这里我将测试块添加到最后,你也可以根据需要在对应的位置进行添加,整体的 usage.rst 文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Usage
=====

.. _installation:

Installation
------------

To use Lumache, first install it using pip:

.. code-block:: console

(.venv) $ pip install lumache

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
:raise lumache.InvalidKindError: If the kind is invalid.
:return: The ingredients list.
:rtype: list[str]

.. py:exception:: lumache.InvalidKindError

Raised if the kind is invalid.

The ``kind`` parameter should be either ``"meat"``, ``"fish"``,
or ``"veggies"``. Otherwise, :py:func:`lumache.get_random_ingredients`
will raise an exception.

>>> import lumache
>>> lumache.get_random_ingredients()
['shells', 'gorgonzola', 'parsley']

doctest 包括要运行的 Python 指令,前面有 >>> 标准的 Python 解释器提示符,以及每条指令的预期输出。通过这种方式,Sphinx 可以检查实际输出是否与预期输出匹配。

为了观察 doctest 失败是什么样子(而不是上面的代码错误),让我们首先不正确地编写返回值。在项目根目录(也就是docs的上级目录)中创建一个 lumache.py 文件,文件内容如下:

1
2
3
def get_random_ingredients(kind=None):
"""Return a list of random ingredients as strings."""
return ["eggs", "bacon", "spam"]

现在可以运行测试语句来执行文档的测试,显然,这个测试会失败:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 如果没有make程序也可以使用这个语句进行测试 sphinx-build -b doctest source build
$ make doctest
正在运行 Sphinx v6.2.1
正在创建输出目录... 完成
正在加载 Pickle 序列化的环境... 完成
正在构建 [mo]: 0 个 po 文件的目标文件已过期
正在写入输出……
正在构建 [doctest]: 2 个源文件的目标文件已过期
正在更新环境:[扩展发生了变化 ('sphinx.ext.doctest')] 有 2 个新增文件,有 0 个文件已被修改,有 0 个文件已被移除
正在读取源文件……[ 50%] index
正在读取源文件……[100%] usage
正在查找当前已过期的文件……没有找到已过期文件
正在 Pickle 序列化环境... 完成
正在校验一致性... 完成
running tests...

Document: usage
---------------
**********************************************************************
File "usage.rst", line 42, in default
Failed example:
lumache.get_random_ingredients()
Expected:
['shells', 'gorgonzola', 'parsley']
Got:
['eggs', 'bacon', 'spam']
**********************************************************************
1 items had failures:
1 of 2 in default
2 tests in 1 items.
1 passed and 1 failed.
***Test Failed*** 1 failures.

Doctest summary
===============
2 tests
1 failure in tests
0 failures in setup code
0 failures in cleanup code

====================== 最长读取耗时 =======================
0.030 usage
0.027 index
构建完成但存在问题。
make: *** [Makefile:20:doctest] 错误 1

现在,我们将代码进行修改,使其通过测试,修改后的代码如下:

1
2
3
def get_random_ingredients(kind=None):
"""Return a list of random ingredients as strings."""
return ["shells", "gorgonzola", "parsley"]

再次运行测试,可以看到测试通过了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
正在运行 Sphinx v6.2.1
正在加载 Pickle 序列化的环境... 完成
正在构建 [mo]: 0 个 po 文件的目标文件已过期
正在写入输出……
正在构建 [doctest]: 2 个源文件的目标文件已过期
正在更新环境:有 0 个新增文件,有 0 个文件已被修改,有 0 个文件已被移除
正在读取源文件……
正在查找当前已过期的文件……没有找到已过期文件
running tests...

Document: usage
---------------
1 items passed all tests:
2 tests in default
2 tests in 1 items.
2 passed and 0 failed.
Test passed.

Doctest summary
===============
2 tests
0 failures in tests
0 failures in setup code
0 failures in cleanup code
构建成功。

已完成源文件的文档测试,结果保存在 build/doctest/output.txt 中,请查阅。

自动生成文档

Sphinx 可以根据代码中的 docstring 自动生成文档,这样可以减少文档的编写工作量,同时也可以保证文档与代码的一致性。

文档字符串自动生成文档

要使用这个功能,需要先启动 Sphinx 的 autodoc 扩展。在 conf.py 文件中添加如下内容:

1
2
3
4
5
extensions = [
'sphinx.ext.duration',
'sphinx.ext.doctest',
'sphinx.ext.autodoc',
]

接下来我们先将 lumache.py 文件中的代码进行修改,添加一个异常类以及函数的docstring,修改后的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class InvalidKindError(Exception):
"""Raised if the kind is invalid."""
pass

def 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]

"""
return ["shells", "gorgonzola", "parsley"]

然后,将 .. py:function 和 .. py:exception 标记指向原始的 python 文件,使用自动生成字段 autofunction 、 autoexception 添加到文档中,这样 Sphinx 就会自动将这些内容添加到文档中。

修改后的 usage.rst 文档如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Usage
=====

.. _installation:

Installation
------------

To use Lumache, first install it using pip:

.. code-block:: console

(.venv) $ pip install lumache

Creating recipes
----------------

To retrieve a list of random ingredients,
you can use the ``lumache.get_random_ingredients()`` function:

.. autofunction:: lumache.get_random_ingredients

.. autoexception:: lumache.InvalidKindError

The ``kind`` parameter should be either ``"meat"``, ``"fish"``,
or ``"veggies"``. Otherwise, :py:func:`lumache.get_random_ingredients`
will raise an exception.

>>> import lumache
>>> lumache.get_random_ingredients()
['shells', 'gorgonzola', 'parsley']

现在,运行 make html 命令,可以看到文档中已经包含了我们添加的内容,和之前手写的文档没有什么不同:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ make html
正在运行 Sphinx v6.2.1
正在加载 Pickle 序列化的环境... 完成
正在构建 [mo]: 0 个 po 文件的目标文件已过期
正在写入输出……
正在构建 [html]: 0 个源文件的目标文件已过期
正在更新环境:有 0 个新增文件,有 1 个文件已被修改,有 0 个文件已被移除
正在读取源文件……[100%] usage
正在查找当前已过期的文件……没有找到已过期文件
正在 Pickle 序列化环境... 完成
正在校验一致性... 完成
正在准备写入文档... 完成
正在写入输出……[ 50%] index
正在写入输出……[100%] usage
正在生成索引... genindex 完成
正在写入附加页面... search 完成
正在复制静态文件... 完成
正在复制额外文件... 完成
正在导出 English (code: en) 的搜索索引... 完成
正在导出对象清单... 完成

====================== 最长读取耗时 =======================
0.049 usage
构建成功。

HTML 页面保存在 build/html 目录。

使用签名和文档字符串自动生成文档

生成全面的API参考

在使用时 sphinx.ext.autodoc 使代码和文档保持同步变得容易得多,但它仍然需要您编写 auto* 指令为您要记录的每个对象指定。Sphinx提供了另一个级别的自动化: autosummary 。

这个 autosummary 指令生成的文档包含所有使用 autodoc 指令的地方。

要使用它,需要先启用扩展:

1
2
3
4
5
6
extensions = [
'sphinx.ext.duration',
'sphinx.ext.doctest',
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
]

接着,创建一个新的 rst 文件,命名为 api.rst ,并添加如下内容:

1
2
3
4
5
6
7
API reference
=============
.. autosummary::
:toctree: _autosummary

lumache.get_random_ingredients
lumache.InvalidKindError

别忘了将 api.rst 文件添加到 index.rst 文件中:

1
2
3
4
5
6
7
.. toctree::
:maxdepth: 2
:caption: Contents:

installation
usage
api

最后,在构建完运行 make html ,它将包含两个新页面:

  • api.html ,对应于 docs/source/api.rst 并包含一个表,其中包含您在 autosummary 指令(在本例中,只有一个)。
  • generated/lumache.html ,对应于自动创建的文件 generated/lumache.rst 并包含模块成员的摘要,在本例中为一个函数和一个异常。

摘要页面中的每个链接都会将您带到您最初使用相应 autodoc 指令,在本例中为 usage.rst 文件。

自动生成摘要首页

自动生成摘要api

自动生成摘要lumache

总结

本文介绍了 Sphinx 的基本用法,包括安装、配置、使用、自定义主题、自动化文档生成等。Sphinx 是一个非常强大的文档生成工具,可以帮助我们快速生成文档,提高文档的质量,减少文档的维护成本。

主要的内容均来自于 Sphinx 官方文档中的 《使用sphinx》一节,本文只是对官方文档的一个简单翻译和总结,希望能够帮助到大家。

参考

文章目录
  1. 1. Sphinx
    1. 1.1. 安装
    2. 1.2. 设置文档源
    3. 1.3. 构建文档
    4. 1.4. 定制
      1. 1.4.1. 内置扩展
      2. 1.4.2. 主题
    5. 1.5. 叙事性文档
      1. 1.5.1. 跨多页组织文档
      2. 1.5.2. 添加交叉引用
    6. 1.6. 使用Sphinx描述代码
      1. 1.6.1. 记录Python对象
      2. 1.6.2. 交叉引用Python对象
    7. 1.7. 文档测试
    8. 1.8. 自动生成文档
      1. 1.8.1. 文档字符串自动生成文档
      2. 1.8.2. 生成全面的API参考
  2. 2. 总结
  3. 3. 参考