如何为 NumPy 文档做出贡献#

本指南将帮助您决定贡献什么以及如何将其提交到官方 NumPy 文档。

文档团队会议#

NumPy 社区已设定了改进其文档的坚定目标。我们定期在 Zoom 上召开文档会议(日期在 numpy-discussion 邮件列表 上公布),欢迎每个人参加。如果您有疑问或需要有人指导您完成第一步,请随时联系我们——我们很乐意提供帮助。会议记录是 在 hackmd.io 上 进行记录并存储在 NumPy Archive 存储库 中。

需要什么#

NumPy 文档 对细节进行了详细说明。当文档 构建 时,API 参考文档直接从代码中的 文档字符串 中生成。虽然我们为向用户公开的每个函数和类提供了较为全面的参考文档,但其中一些函数和类缺少使用示例。

我们缺少范围更广的文档,例如教程、操作指南和说明。报告缺陷是做出贡献的另一种方式。我们讨论这两方面。

修复缺陷#

我们急切地希望了解并修复文档缺陷。但是,为了解决最大的问题,最终我们不得不延迟或忽略一些错误报告。以下是最佳缺陷。

**技术不准确**优先 - 文档字符串缺少参数、功能/参数/方法描述有误等。其他“结构”缺陷(例如损坏的链接)也优先处理。所有这些修复都易于确认并实施。如果您知道如何操作,则可以提交带有修复的 pull 请求 (PR); 否则,请 公开问题

**错别字和拼写错误**处于较低级别;我们欢迎听取有关它们的报告,但可能无法立即修复它们。这些也可以作为 pull 请求或问题进行处理。

明显的**措辞**错误(如遗漏“not”)属于错别字类别,但其他改写 - 即使是语法 - 需要判断,这提高了标准。通过首先将修复作为问题提出,来试探水温。

在 C 扩展模块(如 numpy.ndarray.transpose、numpy.array 等)中定义的一些函数/对象在其 _add_newdocs.py 中分别定义了文档字符串。

贡献新页面#

您在使用我们的文档时遇到的挫折是我们需要修复内容的最佳指南。

如果您编写缺少的文档,就加入了开源的前沿,但仅仅让我们知道缺少了什么也是一项有意义的贡献。如果您想撰写文档,请将您的想法提交到 邮件列表 中,以便获得进一步的想法和反馈。如果您想要向我们指出差距,请 公开问题。请参阅 此问题 以获取示例。

如果您正在寻找主题,我们用于文档编写的正式路线图是 *Numpy 增强提案 (NEP)*,NEP 44 - 重构 Numpy 文档 。它确定了我们的文档需要帮助的领域,并列出了我们希望看到的若干补充,包括 Jupyter 笔记本

文档框架#

有一些公式可以用来撰写有用的文档,并且四个公式几乎涵盖所有内容。之所以有四个公式,是因为有四类文档 - tutorialhow-to guideexplanationreference。文档以这种方式划分的见解属于 Daniele Procida 及其 Diátaxis 框架。当您开始编写文档或提出一个文档时,请记住它将属于哪种类型。

NumPy 教程#

除了 NumPy 源代码树中包含的文档外,你还可以以 Jupyter Notebook 格式向NumPy 教程页面提交内容。这套教程和教育资料旨在由 NumPy 项目提供高质量的资源,用于自学和授课。这些资源是在一个单独的 GitHub 代码库numpy-tutorials中开发的,你可以在其中查看现有的笔记本、打开问题以建议新主题或以拉取请求的形式提交你自己的教程。

更多有关贡献的信息#

不必担心英语不是你的母语,或者你只能想出草稿。开源是一项社区工作。尽你所能 - 我们会帮助修复问题。

图像和真实数据可以使文字更具吸引力和说服力,但务必要确保你所使用的资源具有适当的许可证并可用。我们再次重申,即使是一个粗略的艺术品创意也可以由他人进行完善。

目前,NumPy 唯一接受的数据格式是 pandas、SciPy 或 Matplotlib 等其他 Python 科学库也使用的格式。我们正在开发一个支持更多格式的程序包;如需详细信息,请与我们联系。

NumPy 文档保存在源代码树中。若要将文档放入代码库,你必须下载代码树,构建它,然后提交一个拉取请求。如果 GitHub 和拉取请求对你来说很新,请查看我们的贡献者指南

我们的标记语言是 reStructuredText (rST),它比 Markdown 更复杂。许多 Python 项目用于构建和链接项目文档的工具 Sphinx 将 rST 转换为 HTML 和其他格式。有关 rST 的更多信息,请参阅快速 reStructuredText 指南reStructuredText 初学者教程

间接贡献#

如果你遇到了会对 NumPy 文档有帮助的外部资料,请通过打开一个问题告诉我们。

你无需在此处做出贡献,即可为 NumPy 做出贡献。如果你在你的博客上写一篇教程、创建一个 YouTube 视频或在 Stack Overflow 和其他网站上回答问题,你就已经做出了贡献。

文档格式#

用户文档#

  • 一般来说,我们在用户指南中遵循Google 开发者文档格式指南

  • NumPy 格式适用于以下情形

    • Google 没有指导,或者

    • 我们不赞成使用 Google 风格

    我们的当前规则

    • 我们使用 indices 作为 index 的复数形式,而不是 indexes,遵循 numpy.indices 的先例。

    • 为了一致性,我们还使用 matrices 作为 matrix 的复数形式。

  • 如果语法问题没有在 NumPy 或 Google 规则中得到充分说明,我们将根据最新版 《芝加哥风格手册》 中的“语法和用法”一节做出决定。

  • 欢迎向我们 提出意见,说明我们应添加到 NumPy 风格规则中的用例。

文档字符串#

Sphinx 与 NumPy 规范结合使用时,您应该使用 numpydoc 扩展,以便正确处理文档字符串。例如,Sphinx 将从您的文档字符串中提取 Parameters 部分,并将其转换为字段列表。使用 numpydoc 还可以避免普通 Sphinx 在遇到 Sphinx 预期不会在文档字符串中找到的 NumPy 文档字符串规范(如章节标题(例如 -------------))时产生的 reStructuredText 错误。

它可通过以下方式获取

请注意,对于 NumPy 中的文档,没有必要在示例开头执行 import numpy as np

请使用 numpydoc 格式化标准,如其 示例 中所示。

记录 C/C++ 代码#

NumPy 使用 Doxygen 来解析格式特殊的 C/C++ 注释块。这会生成 XML 文件,然后由 Breathe 转换为 RST,Sphinx 会使用 RST。

完成文档流程需要执行三个步骤:

1. 编写注释块#

虽然仍未设置要遵循的注释风格,但由于与当前存在的非索引注释块相似,Javadoc 比其他风格更可取。

注意

请参阅 “记录代码”

此项是 JavaDoc 样式的外观:

/**
 * This a simple brief.
 *
 * And the details goes here.
 * Multi lines are welcome.
 *
 * @param  num  leave a comment for parameter num.
 * @param  str  leave a comment for the second parameter.
 * @return      leave a comment for the returned value.
 */
int doxy_javadoc_example(int num, const char *str);

而此项为呈现后的外观:

警告

doxygenfunction: 无法解决带有“numpy”项目中的 doxygen xml 输出目录为 ../build/doxygen/xml 中的 None 参数的函数“doxy_javadoc_example”。可能的匹配项

- int doxy_javadoc_example(int num, const char *str)
- int doxy_javadoc_example(int num, const char *str)

对于行注释,可以使用三个正斜杠。例如:

/**
 *  Template to represent limbo numbers.
 *
 *  Specializations for integer types that are part of nowhere.
 *  It doesn't support with any real types.
 *
 *  @param Tp Type of the integer. Required to be an integer type.
 *  @param N  Number of elements.
*/
template<typename Tp, std::size_t N>
class DoxyLimbo {
 public:
    /// Default constructor. Initialize nothing.
    DoxyLimbo();
    /// Set Default behavior for copy the limbo.
    DoxyLimbo(const DoxyLimbo<Tp, N> &l);
    /// Returns the raw data for the limbo.
    const Tp *data();
 protected:
    Tp p_data[N]; ///< Example for inline comment.
};

而此项为呈现后的外观:

template<typename Tp, std::size_t N>
class DoxyLimbo#

表示不定数的模板。

不属于任何部分的整数类型的特殊化。它不支持任何真实类型。

参数 Tp:

整数类型。要求为整数类型。

参数 N:

元素数量。

公共函数

DoxyLimbo()#

默认构造函数。不初始化任何内容。

DoxyLimbo(const DoxyLimbo<Tp, N> &l)#

设定复制不稳定状态的默认行为。

const Tp *data()#

返回 limbo 的原始数据。

DoxyLimbo()

默认构造函数。不初始化任何内容。

DoxyLimbo(const DoxyLimbo<Tp, N> &l)

设定复制不稳定状态的默认行为。

const Tp *data()

返回 limbo 的原始数据。

受保护的属性

Tp p_data[N]#

内联注释示例。

常用的 Doxygen 标记:#

注意

有关更多标记/命令,请参阅 https://www.doxygen.nl/manual/commands.html

@brief

声明一个作为简要说明的段落。默认情况下,文档块的第一句话会自动视为简要说明,因为在 doxygen 配置中启用了选项 JAVADOC_AUTOBRIEF

@details

就像 @brief 以简洁描述开始,@details 以详细描述开始。您还可以开始一个新段落(空白行),然后再使用 @details 命令。

@param

以函数参数名称 <parameter-name>开始对参数描述,后面是对参数的描述。检查参数的存在,如果未在函数声明或定义中提供此参数(或任何其他参数)的文档或不存在,则给予警告。

@return

开始对函数的返回值描述。多个相邻的 @return 命令将连接成一个段落。当遇到空白行或其他分段命令时,@return 描述结束。

@code/@endcode

开始/结束代码块。代码块的处理方式与普通文本不同。代码块被解释为源代码。

@rst/@endrst

开始/结束 reST 标记块。

示例#

看看下面的示例:

/**
 * A comment block contains reST markup.
 * @rst
 * .. note::
 *
 *   Thanks to Breathe_, we were able to bring it to Doxygen_
 *
 * Some code example::
 *
 *   int example(int x) {
 *       return x * 2;
 *   }
 * @endrst
 */
void doxy_reST_example(void);

而此项为呈现后的外观:

警告

doxygenfunction: 无法使用目录 ../build/doxygen/xml 中为项目 “numpy” 生成的 doxygen xml 输出将函数 “doxy_reST_example” 与 None 参数结合解决。潜在匹配

- void doxy_reST_example(void)
- void doxy_reST_example(void)

2. 提供 Doxygen#

并非所有头文件都被自动收集。您必须在 Doxygen 的子配置文件中添加所需的 C/C++ 头文件路径。

子配置文件具有唯一名称 .doxyfile,您通常可以在包含已放入文档中头的目录附近找到此名称。如果您在距离要添加的头最接近(2 深度)的路径中未找到一个配置文件,则需要创建一个新配置文件。

子配置文件可以接受任何 Doxygen 配置选项,但不要覆盖或重新初始化任何配置选项,而仅使用连接符 “+=”。例如

# to specify certain headers
INPUT += @CUR_DIR/header1.h \
         @CUR_DIR/header2.h
# to add all headers in certain path
INPUT += @CUR_DIR/to/headers
# to define certain macros
PREDEFINED += C_MACRO(X)=X
# to enable certain branches
PREDEFINED += NPY_HAVE_FEATURE \
              NPY_HAVE_FEATURE2

注意

@CUR_DIR 是返回子配置文件的当前目录路径的模板常数。

3. Inclusion 指令#

Breathe 提供了广泛的自定义指令,以便将 Doxygen 生成的文档转换至 reST 文件。

注意

有关详细信息,请查看 “Directives & Config Variables

常见指令:#

doxygenfunction

该指令为单个函数生成适当的输出。要求函数名称在项目中是唯一的。

.. doxygenfunction:: <function name>
    :outline:
    :no-link:

查看 示例 以了解其实际效果。

doxygenclass

该指令为单个类生成适当的输出。它采用标准的项目、路径、轮廓和无链接选项,并附加成员、受保护的成员、私有成员、未记录的成员、成员组和仅成员等选项

.. doxygenclass:: <class name>
   :members: [...]
   :protected-members:
   :private-members:
   :undoc-members:
   :membergroups: ...
   :members-only:
   :outline:
   :no-link:

查看 doxygenclass 文档 以了解更多详情并了解其实际效果。

doxygennamespace

该指令为名称空间的内容生成适当的输出。它采用标准的项目、路径、轮廓和无链接选项,并附加仅内容、成员、受保护的成员、私有成员和未记录的成员等选项。如要引用嵌套的名称空间,必须提供完整的名称空间路径,例如嵌套在 foo 名称空间内的 bar 名称空间即为 foo::bar。

.. doxygennamespace:: <namespace>
   :content-only:
   :outline:
   :members:
   :protected-members:
   :private-members:
   :undoc-members:
   :no-link:

查看 doxygennamespace 文档 以了解更多详情并了解其实际效果。

doxygengroup

该指令为 doxygen 组的内容生成适当的输出。可以在源代码注释中使用特定的 doxygen 标记来声明 doxygen 组,如 doxygen 分组文档 中所述。

它采用标准的项目、路径、轮廓和无链接选项,并附加仅内容、成员、受保护的成员、私有成员和未记录的成员等选项。

.. doxygengroup:: <group name>
   :content-only:
   :outline:
   :members:
   :protected-members:
   :private-members:
   :undoc-members:
   :no-link:
   :inner:

查看 doxygengroup 文档 以了解更多详情并了解其实际效果。

旧版指令#

如果某个函数、模块或 API 处于旧版模式,表明出于向后兼容性的原因而保留,但不建议在新代码中使用,则可以使用 .. legacy:: 指令。

默认情况下,如在无参数的情况下使用,legacy 指令将生成以下输出

旧版

该子模块被视为旧版,并且不会再收到更新。这还可能意味着它会在未来的 NumPy 版本中被移除。

我们强烈建议您添加自定义消息,例如用新的 API 替换旧 API

.. legacy::

   For more details, see :ref:`distutils-status-migration`.

此消息将附加到默认消息,并创建以下输出:

旧版

该子模块被视为旧版,并且不会再收到更新。这还可能意味着它会在未来的 NumPy 版本中被移除。有关更多详情,请参见 numpy.distutils 的状态和迁移建议

最后,如果您想要引用函数、方法(或任何自定义对象),而不是子模块,您可以使用可选参数

.. legacy:: function

这将创建以下输出

旧版

此函数被认为是遗留函数,将不再收到更新。这也可能意味着它将在未来的 NumPy 版本中被移除。

文档阅读#

  • 技术作家领先组织Write the Docs,举办会议、提供学习资源并运营 Slack 频道。

  • “每个工程师也是一位作家,”Google 的技术写作资源合集说道,其中包括为开发人员准备的免费在线课程,用于规划和编写文档。

  • Software Carpentry的使命是教授研究人员软件。除了托管课程之外,该网站还解释了如何有效地表达想法。