标签归档:python-sphinx

如何使用Sphinx的自动文档来记录类的__init __(self)方法?

问题:如何使用Sphinx的自动文档来记录类的__init __(self)方法?

Sphinx默认情况下不会为__init __(self)生成文档。我尝试了以下方法:

.. automodule:: mymodule
    :members:

..autoclass:: MyClass
    :members:

在conf.py中,设置以下内容只会将__init __(self)文档字符串附加到类文档字符串(Sphinx autodoc文档似乎同意这是预期的行为,但未提及我要解决的问题):

autoclass_content = 'both'

Sphinx doesn’t generate docs for __init__(self) by default. I have tried the following:

.. automodule:: mymodule
    :members:

and

..autoclass:: MyClass
    :members:

In conf.py, setting the following only appends the __init__(self) docstring to the class docstring (the Sphinx autodoc documentation seems to agree that this is the expected behavior, but mentions nothing regarding the problem I’m trying to solve):

autoclass_content = 'both'

回答 0

这是三种选择:

  1. 为了确保__init__()始终记录autodoc-skip-member在文档中,可以在conf.py中使用。像这样:

    def skip(app, what, name, obj, would_skip, options):
        if name == "__init__":
            return False
        return would_skip
    
    def setup(app):
        app.connect("autodoc-skip-member", skip)

    这明确定义了__init__不被跳过(默认情况下为跳过)。仅一次指定此配置,并且.rst源中的每个类都不需要任何其他标记。

  2. special-members选项已在Sphinx 1.1添加。它使“特殊”成员(名称如的成员__special__)由autodoc记录。

    从Sphinx 1.2开始,此选项接受参数,这使其比以前更有用。

  3. 用途automethod

    .. autoclass:: MyClass     
       :members: 
    
       .. automethod:: __init__

    这必须为每个类添加(不能与一起使用automodule,如对此答案的第一个修订版的注释中指出的那样)。

Here are three alternatives:

  1. To ensure that __init__() is always documented, you can use autodoc-skip-member in conf.py. Like this:

    def skip(app, what, name, obj, would_skip, options):
        if name == "__init__":
            return False
        return would_skip
    
    def setup(app):
        app.connect("autodoc-skip-member", skip)
    

    This explicitly defines __init__ not to be skipped (which it is by default). This configuration is specified once, and it does not require any additional markup for every class in the .rst source.

  2. The special-members option was added in Sphinx 1.1. It makes “special” members (those with names like __special__) be documented by autodoc.

    Since Sphinx 1.2, this option takes arguments which makes it more useful than it was previously.

  3. Use automethod:

    .. autoclass:: MyClass     
       :members: 
    
       .. automethod:: __init__
    

    This has to be added for every class (cannot be used with automodule, as pointed out in a comment to the first revision of this answer).


回答 1

你近了 您可以autoclass_contentconf.py文件中使用该选项:

autoclass_content = 'both'

You were close. You can use the autoclass_content option in your conf.py file:

autoclass_content = 'both'

回答 2

在过去的几年中,我autodoc-skip-member为各种不相关的Python项目编写了多种回调类型,因为我希望使用诸如之类的方法__init__()__enter__()并将__exit__()其显示在我的API文档中(毕竟,这些“特殊方法”是API的一部分,还有什么更好的地方记录它们,而不是在特殊方法的文档字符串中记录它们。

最近,我采用了最佳的实现,并将其纳入了我的Python项目之一(这是文档)。实现基本上可以归结为:

import types

def setup(app):
    """Enable Sphinx customizations."""
    enable_special_methods(app)


def enable_special_methods(app):
    """
    Enable documenting "special methods" using the autodoc_ extension.

    :param app: The Sphinx application object.

    This function connects the :func:`special_methods_callback()` function to
    ``autodoc-skip-member`` events.

    .. _autodoc: http://www.sphinx-doc.org/en/stable/ext/autodoc.html
    """
    app.connect('autodoc-skip-member', special_methods_callback)


def special_methods_callback(app, what, name, obj, skip, options):
    """
    Enable documenting "special methods" using the autodoc_ extension.

    Refer to :func:`enable_special_methods()` to enable the use of this
    function (you probably don't want to call
    :func:`special_methods_callback()` directly).

    This function implements a callback for ``autodoc-skip-member`` events to
    include documented "special methods" (method names with two leading and two
    trailing underscores) in your documentation. The result is similar to the
    use of the ``special-members`` flag with one big difference: Special
    methods are included but other types of members are ignored. This means
    that attributes like ``__weakref__`` will always be ignored (this was my
    main annoyance with the ``special-members`` flag).

    The parameters expected by this function are those defined for Sphinx event
    callback functions (i.e. I'm not going to document them here :-).
    """
    if getattr(obj, '__doc__', None) and isinstance(obj, (types.FunctionType, types.MethodType)):
        return False
    else:
        return skip

是的,文档比逻辑更多:-)。autodoc-skip-member相对于使用special-members选项(对我而言)定义这样的回调的好处是,该special-members选项还可以记录属性__weakref__(例如,在所有新样式类AFAIK上可用)的文档,而我认为这些属性根本没有用。回调方法避免了这种情况(因为它仅适用于函数/方法,而忽略其他属性)。

Over the past years I’ve written several variants of autodoc-skip-member callbacks for various unrelated Python projects because I wanted methods like __init__(), __enter__() and __exit__() to show up in my API documentation (after all, these “special methods” are part of the API and what better place to document them than inside the special method’s docstring).

Recently I took the best implementation and made it part of one of my Python projects (here’s the documentation). The implementation basically comes down to this:

import types

def setup(app):
    """Enable Sphinx customizations."""
    enable_special_methods(app)


def enable_special_methods(app):
    """
    Enable documenting "special methods" using the autodoc_ extension.

    :param app: The Sphinx application object.

    This function connects the :func:`special_methods_callback()` function to
    ``autodoc-skip-member`` events.

    .. _autodoc: http://www.sphinx-doc.org/en/stable/ext/autodoc.html
    """
    app.connect('autodoc-skip-member', special_methods_callback)


def special_methods_callback(app, what, name, obj, skip, options):
    """
    Enable documenting "special methods" using the autodoc_ extension.

    Refer to :func:`enable_special_methods()` to enable the use of this
    function (you probably don't want to call
    :func:`special_methods_callback()` directly).

    This function implements a callback for ``autodoc-skip-member`` events to
    include documented "special methods" (method names with two leading and two
    trailing underscores) in your documentation. The result is similar to the
    use of the ``special-members`` flag with one big difference: Special
    methods are included but other types of members are ignored. This means
    that attributes like ``__weakref__`` will always be ignored (this was my
    main annoyance with the ``special-members`` flag).

    The parameters expected by this function are those defined for Sphinx event
    callback functions (i.e. I'm not going to document them here :-).
    """
    if getattr(obj, '__doc__', None) and isinstance(obj, (types.FunctionType, types.MethodType)):
        return False
    else:
        return skip

Yes, there’s more documentation than logic :-). The advantage of defining an autodoc-skip-member callback like this over the use of the special-members option (for me) is that the special-members option also enables documentation of properties like __weakref__ (available on all new-style classes, AFAIK) which I consider noise and not useful at all. The callback approach avoids this (because it only works on functions/methods and ignores other attributes).


回答 3

尽管这是一个较旧的文章,但对于那些现在为止正在查找它的人,版本1.8中还引入了另一个解决方案。根据文档,您可以将special-member密钥添加 到autodoc_default_options中conf.py

例:

autodoc_default_options = {
    'members': True,
    'member-order': 'bysource',
    'special-members': '__init__',
    'undoc-members': True,
    'exclude-members': '__weakref__'
}

Even though this is an older post, for those who are looking it up as of now, there is also another solution introduced in version 1.8. According to the documentation, You can add the special-member key in the autodoc_default_options to your conf.py.

Example:

autodoc_default_options = {
    'members': True,
    'member-order': 'bysource',
    'special-members': '__init__',
    'undoc-members': True,
    'exclude-members': '__weakref__'
}

回答 4

这是一个变体,仅__init__当具有参数时才包括:

import inspect

def skip_init_without_args(app, what, name, obj, would_skip, options):
    if name == '__init__':
        func = getattr(obj, '__init__')
        spec = inspect.getfullargspec(func)
        return not spec.args and not spec.varargs and not spec.varkw and not spec.kwonlyargs
    return would_skip

def setup(app):
    app.connect("autodoc-skip-member", skip_init_without_args)

This is a variant which only includes __init__ if it has arguments:

import inspect

def skip_init_without_args(app, what, name, obj, would_skip, options):
    if name == '__init__':
        func = getattr(obj, '__init__')
        spec = inspect.getfullargspec(func)
        return not spec.args and not spec.varargs and not spec.varkw and not spec.kwonlyargs
    return would_skip

def setup(app):
    app.connect("autodoc-skip-member", skip_init_without_args)

sphinx-build失败-autodoc无法导入/查找模块

问题:sphinx-build失败-autodoc无法导入/查找模块

我正在尝试开始使用Sphinx,似乎遇到了很多问题。

命令: docs/sphinx-quickstart

我回答所有问题,一切正常。

命令: docs/ls

一切看起来都很正常。结果:build Makefile source

命令: sphinx-build -d build/doctrees source build/html

似乎有效。我能够打开index.html文件,并看到我想要的“外壳”。

当我尝试将实际的源代码作为source文件夹时,我遇到了问题。

命令: sphinx-build -d build/doctrees ../ys_utils build/html

结果:

Making output directory...
Running Sphinx v1.1.3
loading pickled environment... not yet created
No builder selected, using default: html
loading intersphinx inventory from http://docs.python.org/objects.inv...
building [html]: targets for 1 source files that are out of date
updating environment: 1 added, 0 changed, 0 removed
Traceback (most recent call last):                                                                                               
  File "/usr/local/lib/python2.6/dist-packages/Sphinx-1.1.3-py2.6.egg/sphinx/ext/autodoc.py", line 321, in import_object
    __import__(self.modname)
ImportError: No module named ys_utils
Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/Sphinx-1.1.3-py2.6.egg/sphinx/ext/autodoc.py", line 321, in import_object
    __import__(self.modname)
ImportError: No module named ys_utils.test_validate_ut
Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/Sphinx-1.1.3-py2.6.egg/sphinx/ext/autodoc.py", line 321, in import_object
    __import__(self.modname)
ImportError: No module named ys_utils.git_utils
Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/Sphinx-1.1.3-py2.6.egg/sphinx/ext/autodoc.py", line 321, in import_object
    __import__(self.modname)
ImportError: No module named setup.setup

/home/ricomoss/workspace/nextgen/ys_utils/ys_utils.rst:4: WARNING: autodoc can't import/find module 'ys_utils', it reported error: "No module named ys_utils", please check your spelling and sys.path
/home/ricomoss/workspace/nextgen/ys_utils/ys_utils.rst:10: WARNING: autodoc can't import/find module 'ys_utils.test_validate_ut', it reported error: "No module named ys_utils.test_validate_ut", please check your spelling and sys.path
/home/ricomoss/workspace/nextgen/ys_utils/ys_utils.rst:12: WARNING: don't know which module to import for autodocumenting u'UnitTests' (try placing a "module" or "currentmodule" directive in the document, or giving an explicit module name)
/home/ricomoss/workspace/nextgen/ys_utils/ys_utils.rst:18: WARNING: autodoc can't import/find module 'ys_utils.git_utils', it reported error: "No module named ys_utils.git_utils", please check your spelling and sys.path
/home/ricomoss/workspace/nextgen/ys_utils/ys_utils.rst:24: WARNING: autodoc can't import/find module 'setup.setup', it reported error: "No module named setup.setup", please check your spelling and sys.path
WARNING: master file /home/ricomoss/workspace/nextgen/ys_utils/index.rst not found
looking for now-outdated files... none found
pickling environment... done
checking consistency... /home/ricomoss/workspace/nextgen/ys_utils/ys_utils.rst:: WARNING: document isn't included in any toctree
done
preparing documents... done
writing output... [ 50%] index                                                                                                   
Exception occurred:
  File "/usr/local/lib/python2.6/dist-packages/Sphinx-1.1.3-py2.6.egg/sphinx/environment.py", line 1213, in get_doctree
    f = open(doctree_filename, 'rb')
IOError: [Errno 2] No such file or directory: '/home/ricomoss/workspace/nextgen/docs/build/doctrees/index.doctree'
The full traceback has been saved in /tmp/sphinx-err-jjJ7gM.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
Either send bugs to the mailing list at <http://groups.google.com/group/sphinx-dev/>,
or report them in the tracker at <http://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!

我是Sphinx的新手,并且对此类文档还比较陌生。谁能提供一些建议?

编辑:

我希望能够使用Makefile来处理此问题。到目前为止,我的项目中有两个文件夹。

nextgen/ls

docs ys_utils

我需要nextgen/docs/Makefileys_utils将要拥有的所有其他模块生成HTML 。

I’m trying to get started with Sphinx and seem to have relentless problems.

Command: docs/sphinx-quickstart

I answer all the questions and everything works fine.

Command: docs/ls

Everything looks normal. Result: build Makefile source

Command: sphinx-build -d build/doctrees source build/html

It seems to work. I was able to open the index.html file and see a “shell” of what I’m wanting.

When I try and put my actual source code as the source folder I run into problems.

Command: sphinx-build -d build/doctrees ../ys_utils build/html

Result:

Making output directory...
Running Sphinx v1.1.3
loading pickled environment... not yet created
No builder selected, using default: html
loading intersphinx inventory from http://docs.python.org/objects.inv...
building [html]: targets for 1 source files that are out of date
updating environment: 1 added, 0 changed, 0 removed
Traceback (most recent call last):                                                                                               
  File "/usr/local/lib/python2.6/dist-packages/Sphinx-1.1.3-py2.6.egg/sphinx/ext/autodoc.py", line 321, in import_object
    __import__(self.modname)
ImportError: No module named ys_utils
Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/Sphinx-1.1.3-py2.6.egg/sphinx/ext/autodoc.py", line 321, in import_object
    __import__(self.modname)
ImportError: No module named ys_utils.test_validate_ut
Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/Sphinx-1.1.3-py2.6.egg/sphinx/ext/autodoc.py", line 321, in import_object
    __import__(self.modname)
ImportError: No module named ys_utils.git_utils
Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/Sphinx-1.1.3-py2.6.egg/sphinx/ext/autodoc.py", line 321, in import_object
    __import__(self.modname)
ImportError: No module named setup.setup

/home/ricomoss/workspace/nextgen/ys_utils/ys_utils.rst:4: WARNING: autodoc can't import/find module 'ys_utils', it reported error: "No module named ys_utils", please check your spelling and sys.path
/home/ricomoss/workspace/nextgen/ys_utils/ys_utils.rst:10: WARNING: autodoc can't import/find module 'ys_utils.test_validate_ut', it reported error: "No module named ys_utils.test_validate_ut", please check your spelling and sys.path
/home/ricomoss/workspace/nextgen/ys_utils/ys_utils.rst:12: WARNING: don't know which module to import for autodocumenting u'UnitTests' (try placing a "module" or "currentmodule" directive in the document, or giving an explicit module name)
/home/ricomoss/workspace/nextgen/ys_utils/ys_utils.rst:18: WARNING: autodoc can't import/find module 'ys_utils.git_utils', it reported error: "No module named ys_utils.git_utils", please check your spelling and sys.path
/home/ricomoss/workspace/nextgen/ys_utils/ys_utils.rst:24: WARNING: autodoc can't import/find module 'setup.setup', it reported error: "No module named setup.setup", please check your spelling and sys.path
WARNING: master file /home/ricomoss/workspace/nextgen/ys_utils/index.rst not found
looking for now-outdated files... none found
pickling environment... done
checking consistency... /home/ricomoss/workspace/nextgen/ys_utils/ys_utils.rst:: WARNING: document isn't included in any toctree
done
preparing documents... done
writing output... [ 50%] index                                                                                                   
Exception occurred:
  File "/usr/local/lib/python2.6/dist-packages/Sphinx-1.1.3-py2.6.egg/sphinx/environment.py", line 1213, in get_doctree
    f = open(doctree_filename, 'rb')
IOError: [Errno 2] No such file or directory: '/home/ricomoss/workspace/nextgen/docs/build/doctrees/index.doctree'
The full traceback has been saved in /tmp/sphinx-err-jjJ7gM.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
Either send bugs to the mailing list at <http://groups.google.com/group/sphinx-dev/>,
or report them in the tracker at <http://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!

I am a complete newbie to Sphinx and relatively new to this kind of documentation. Can anyone offer some suggestions?

Edit:

I’d like to be able to use a Makefile to handle this. As of now I have two folders in my project.

nextgen/ls

docs ys_utils

I need nextgen/docs/Makefile to generate the HTML for ys_utils and all other modules I’m going to have.


回答 0

Autodoc找不到您的模块,因为它们不在中sys.path

你必须包括在路径到您的模块sys.path在你的conf.py。查看您的顶部conf.py(在导入之后sys),有一条sys.path.insert()语句可以调整。

顺便说一句:您可以使用MakefileSphinx创建的创建文档。刚打电话

make

查看选项。

如果出现问题,请尝试以下操作:

make clean

之前运行make html

Autodoc can’t find your modules, because they are not in sys.path.

You have to include the path to your modules in in the sys.path in your conf.py. Look at the top of your conf.py (just after the import of sys), there is a sys.path.insert() statement, which you can adapt.

By the way: you can use the Makefile created by Sphinx to create your documentation. Just call

make

to see the options.

If something went wrong before try:

make clean

before running make html.


回答 1

听起来os.path.append()对所有人来说还可以,但是如果您遵循conf.py模板,则可以将模块路径插入sys.pathusing 的前面os.path.insert(0, ...),然后添加一个额外的.

import os
import sys
sys.path.insert(0, os.path.abspath('..'))

如果您已经安装你的sphinx项目中使用单独buildsource目录,该呼叫应改为:

sys.path.insert(0, os.path.abspath('../..'))

It sounds like os.path.append() is working OK for folks, but if you follow the conf.py template, you would insert the module path to the front of sys.path using os.path.insert(0, ...), and just add an extra .

import os
import sys
sys.path.insert(0, os.path.abspath('..'))

If you have setup your sphinx project to use separate build and source directories, that call should instead be:

sys.path.insert(0, os.path.abspath('../..'))

回答 2

conf.py

只需将路径添加到您的项目文件夹。

sys.path.append('/home/workspace/myproj/myproj')

in conf.py

just add the path to your project folder.

sys.path.append('/home/workspace/myproj/myproj')

回答 3

如果

  1. 在conf.py中正确设置了模块根路径
  2. __init__.py 放置正确
  3. 第一个语法正确

而且您的autodoc仍然找不到模块…

可能是因为在您的python环境下无法满足这些模块的依赖性。您将要检查所有导入语句是否在模块内正常工作。

If

  1. module root path is correctly set in conf.py
  2. __init__.py is placed correctly
  3. rst syntax is correct

and your autodoc still cannot find the modules…

It may be because the dependencies of those modules are not satisfied under your python environment. You will want to check if all the import statements are working within the modules.


回答 4

我想我是第一次尝试将文件添加到toctree时执行此操作。我认为这是因为我在:maxdepth行和文件名之间留了空白行。

.. Animatrix Concepts documentation master file, created by
   sphinx-quickstart on Thu Mar 22 18:06:15 2012.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Welcome to Animatrix Concepts documentation!
============================================

Contents:

.. toctree::
   :maxdepth: 2

   stuff


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

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

上面是我的index.rst文件。stuff.rst和它驻留在同一目录中。

I think I did this the first time I tried to add a file to the toctree. I think it was because I left out the blank line between the :maxdepth line and the file name.

.. Animatrix Concepts documentation master file, created by
   sphinx-quickstart on Thu Mar 22 18:06:15 2012.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Welcome to Animatrix Concepts documentation!
============================================

Contents:

.. toctree::
   :maxdepth: 2

   stuff


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

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

Above is my index.rst file. stuff.rst resides in the same directory as it.


回答 5

我遇到了同样的错误,但是它是由与其他答案完全不同的原因引起的。

我的.. automethod:: mymodule.func指令实际上应该是:

.. automethod:: mymodule::func`

I got this same error but it was caused by a completely different reason than explained in the other answers.

My .. automethod:: mymodule.func directive should actually have been:

.. automethod:: mymodule::func`

回答 6

您可以使用Pweave和noweb格式生成第一个文档,其中包括嵌入其中的代码的输出。基本上,您编写第一个文件,并在标记的块中嵌入python代码,如下所示:

<<echo=False>>=
print("some text that will appear in the rst file")
@

然后Pweave将执行这些块,并在输出的第一个文件中将其替换为输出,然后可将其与sphinx一起使用。有关其外观的更多详细信息,请参见Pweave reST示例

You can use Pweave and noweb formatting to generate rst documents that include the output of the code embedded in them. Basically, you write your rst file, with python code embedded in marked chunks like this:

<<echo=False>>=
print("some text that will appear in the rst file")
@

and Pweave will execute those chunks, and replace them with their output in a resulting rst file, which you can then use with sphinx. See the Pweave reST example for more details of how it looks.


记录** kwargs参数的正确方法是什么?

问题:记录** kwargs参数的正确方法是什么?

我正在使用sphinx和autodoc插件为我的Python模块生成API文档。虽然可以看到如何很好地记录特定参数,但是找不到如何记录**kwargs参数的示例。

有没有人有一个很好的例子来记录这些问题?

I’m using sphinx and the autodoc plugin to generate API documentation for my Python modules. Whilst I can see how to nicely document specific parameters, I cannot find an example of how to document a **kwargs parameter.

Does anyone have a good example of a clear way to document these?


回答 0

我认为subprocess-module的文档是一个很好的例子。给出顶级/父类的所有参数的详尽列表。然后,只需参考该列表即可查看其他所有出现的**kwargs

I think subprocess-module’s docs is a good example. Give an exhaustive list of all parameters for a top/parent class. Then just refer to that list for all other occurrences of **kwargs.


回答 1

找到这个问题后,我决定使用以下内容,它是有效的Sphinx,效果很好:

def some_function(first, second="two", **kwargs):
    r"""Fetches and returns this thing

    :param first:
        The first parameter
    :type first: ``int``
    :param second:
        The second parameter
    :type second: ``str``
    :param \**kwargs:
        See below

    :Keyword Arguments:
        * *extra* (``list``) --
          Extra stuff
        * *supplement* (``dict``) --
          Additional content

    """

r"""..."""要求,使这个“原始”文档字符串,从而保持\*完好(为狮身人面像拿起作为文字*“强调”,而不是开始)。

选定的格式(带括号的类型的项目符号列表和用短划线分隔的描述)仅与Sphinx提供的自动格式匹配。

一旦完成了使“关键字参数”部分看起来像默认的“参数”部分的工作,从一开始就似乎可以更轻松地滚动自己的参数部分(根据其他一些答案) ,但作为概念证明,**kwargs如果您已经在使用Sphinx,则这是一种使辅助外观更好看的方法。

After finding this question I settled on the following, which is valid Sphinx and works fairly well:

def some_function(first, second="two", **kwargs):
    r"""Fetches and returns this thing

    :param first:
        The first parameter
    :type first: ``int``
    :param second:
        The second parameter
    :type second: ``str``
    :param \**kwargs:
        See below

    :Keyword Arguments:
        * *extra* (``list``) --
          Extra stuff
        * *supplement* (``dict``) --
          Additional content

    """

The r"""...""" is required to make this a “raw” docstring and thus keep the \* intact (for Sphinx to pick up as a literal * and not the start of “emphasis”).

The chosen formatting (bulleted list with parenthesized type and m-dash-separated description) is simply to match the automated formatting provided by Sphinx.

Once you’ve gone to this effort of making the “Keyword Arguments” section look like the default “Parameters” section, it seems like it might be easier to roll your own parameters section from the outset (as per some of the other answers), but as a proof of concept this is one way to achieve a nice look for supplementary **kwargs if you’re already using Sphinx.


回答 2

Sphinx解析的Google Style文档字符串

免责声明:未经测试。

sphinx docstring示例的此切口中,*args**kwargs保持未展开状态

def module_level_function(param1, param2=None, *args, **kwargs):
    """
    ...

    Args:
        param1 (int): The first parameter.
        param2 (Optional[str]): The second parameter. Defaults to None.
            Second line of description should be indented.
        *args: Variable length argument list.
        **kwargs: Arbitrary keyword arguments.

建议使用以下紧凑性解决方案:

    """
    Args:
        param1 (int): The first parameter.
        param2 (Optional[str]): The second parameter. Defaults to None.
            Second line of description should be indented.
        *param3 (int): description
        *param4 (str): 
        ...
        **key1 (int): description 
        **key2 (int): description 
        ...

注意,参数Optional不需要**key

否则,您可以尝试在下方Other Parameters**kwargs下方显式列出* args Keyword Args(请参阅解析的部分):

    """
    Args:
        param1 (int): The first parameter.
        param2 (Optional[str]): The second parameter. Defaults to None.
            Second line of description should be indented.

    Other Parameters:
        param3 (int): description
        param4 (str): 
        ...

    Keyword Args:
        key1 (int): description 
        key2 (int): description 
        ...

Google Style docstrings parsed by Sphinx

Disclaimer: not tested.

From this cutout of the sphinx docstring example, the *args and **kwargs are left unexpanded:

def module_level_function(param1, param2=None, *args, **kwargs):
    """
    ...

    Args:
        param1 (int): The first parameter.
        param2 (Optional[str]): The second parameter. Defaults to None.
            Second line of description should be indented.
        *args: Variable length argument list.
        **kwargs: Arbitrary keyword arguments.

I would suggest the following solution for compactness:

    """
    Args:
        param1 (int): The first parameter.
        param2 (Optional[str]): The second parameter. Defaults to None.
            Second line of description should be indented.
        *param3 (int): description
        *param4 (str): 
        ...
        **key1 (int): description 
        **key2 (int): description 
        ...

Notice how, Optional is not required for **key arguments.

Otherwise, you can try to explicitly list the *args under Other Parameters and **kwargs under the Keyword Args (see parsed sections):

    """
    Args:
        param1 (int): The first parameter.
        param2 (Optional[str]): The second parameter. Defaults to None.
            Second line of description should be indented.

    Other Parameters:
        param3 (int): description
        param4 (str): 
        ...

    Keyword Args:
        key1 (int): description 
        key2 (int): description 
        ...

回答 3

Sphinx的文档中有一个doctstring示例。具体来说,它们显示以下内容:

def public_fn_with_googley_docstring(name, state=None):
"""This function does something.

Args:
   name (str):  The name to use.

Kwargs:
   state (bool): Current state to be in.

Returns:
   int.  The return code::

      0 -- Success!
      1 -- No good.
      2 -- Try again.

Raises:
   AttributeError, KeyError

A really great idea.  A way you might use me is

>>> print public_fn_with_googley_docstring(name='foo', state=None)
0

BTW, this always returns 0.  **NEVER** use with :class:`MyPublicClass`.

"""
return 0

虽然你问过 明确地,我还将指向Google Python样式指南。他们的文档字符串示例似乎暗示着他们没有特别指出kwarg。(other_silly_variable =无)

def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):
"""Fetches rows from a Bigtable.

Retrieves rows pertaining to the given keys from the Table instance
represented by big_table.  Silly things may happen if
other_silly_variable is not None.

Args:
    big_table: An open Bigtable Table instance.
    keys: A sequence of strings representing the key of each table row
        to fetch.
    other_silly_variable: Another optional variable, that has a much
        longer name than the other args, and which does nothing.

Returns:
    A dict mapping keys to the corresponding table row data
    fetched. Each row is represented as a tuple of strings. For
    example:

    {'Serak': ('Rigel VII', 'Preparer'),
     'Zim': ('Irk', 'Invader'),
     'Lrrr': ('Omicron Persei 8', 'Emperor')}

    If a key from the keys argument is missing from the dictionary,
    then that row was not found in the table.

Raises:
    IOError: An error occurred accessing the bigtable.Table object.
"""
pass

ABB有一个关于接受子流程管理文档的可接受答案的问题。如果导入模块,则可以通过inspect.getsource快速查看模块文档字符串。

python解释器中使用Silent Ghost推荐的示例:

>>> import subprocess
>>> import inspect
>>> import print inspect.getsource(subprocess)

当然,您也可以通过帮助功能查看模块文档。例如帮助(子过程)

我个人不喜欢kwargs的子进程docstring,但是像Google的例子一样,它不会像Sphinx文档示例中那样单独列出kwargs。

def call(*popenargs, **kwargs):
"""Run command with arguments.  Wait for command to complete, then
return the returncode attribute.

The arguments are the same as for the Popen constructor.  Example:

retcode = call(["ls", "-l"])
"""
return Popen(*popenargs, **kwargs).wait()

我之所以要回答ABB的问题,是因为值得注意的是,您可以以这种方式查看任何模块的源代码或文档,以获取洞察力和注释代码的灵感。

There is a doctstring example for Sphinx in their documentation. Specifically they show the following:

def public_fn_with_googley_docstring(name, state=None):
"""This function does something.

Args:
   name (str):  The name to use.

Kwargs:
   state (bool): Current state to be in.

Returns:
   int.  The return code::

      0 -- Success!
      1 -- No good.
      2 -- Try again.

Raises:
   AttributeError, KeyError

A really great idea.  A way you might use me is

>>> print public_fn_with_googley_docstring(name='foo', state=None)
0

BTW, this always returns 0.  **NEVER** use with :class:`MyPublicClass`.

"""
return 0

Though you asked about explicitly, I would also point to the Google Python Style Guide. Their docstring example seems to imply that they don’t call out kwargs specifically. (other_silly_variable=None)

def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):
"""Fetches rows from a Bigtable.

Retrieves rows pertaining to the given keys from the Table instance
represented by big_table.  Silly things may happen if
other_silly_variable is not None.

Args:
    big_table: An open Bigtable Table instance.
    keys: A sequence of strings representing the key of each table row
        to fetch.
    other_silly_variable: Another optional variable, that has a much
        longer name than the other args, and which does nothing.

Returns:
    A dict mapping keys to the corresponding table row data
    fetched. Each row is represented as a tuple of strings. For
    example:

    {'Serak': ('Rigel VII', 'Preparer'),
     'Zim': ('Irk', 'Invader'),
     'Lrrr': ('Omicron Persei 8', 'Emperor')}

    If a key from the keys argument is missing from the dictionary,
    then that row was not found in the table.

Raises:
    IOError: An error occurred accessing the bigtable.Table object.
"""
pass

A-B-B has a question about the accepted answer of referencing the subprocess management documentation. If you import a module, you can quickly see the module docstrings via inspect.getsource.

An example from the python interpreter using Silent Ghost’s recommendation:

>>> import subprocess
>>> import inspect
>>> import print inspect.getsource(subprocess)

Of course you can also view the module documentation via help function. For example help(subprocess)

I’m not personally a fan of the subprocess docstring for kwargs as an example, but like the Google example it doesn’t list kwargs seperately as shown in the Sphinx documentation example.

def call(*popenargs, **kwargs):
"""Run command with arguments.  Wait for command to complete, then
return the returncode attribute.

The arguments are the same as for the Popen constructor.  Example:

retcode = call(["ls", "-l"])
"""
return Popen(*popenargs, **kwargs).wait()

I’m including this answer to A-B-B’s question because it’s worth noting that you can review any module’s source or documentation this way for insights and inspiration for commenting your code.


回答 4

如果还有其他人正在寻找一些有效的语法。.这是一个示例文档字符串。这就是我所做的,我希望它对您有用,但是我不能断言它特别符合任何要求。

def bar(x=True, y=False):
    """
    Just some silly bar function.

    :Parameters:
      - `x` (`bool`) - dummy description for x
      - `y` (`string`) - dummy description for y
    :return: (`string`) concatenation of x and y.
    """
    return str(x) + y

def foo (a, b, **kwargs):
    """
    Do foo on a, b and some other objects.

    :Parameters:
      - `a` (`int`) - A number.
      - `b` (`int`, `string`) - Another number, or maybe a string.
      - `\**kwargs` - remaining keyword arguments are passed to `bar`

    :return: Success
    :rtype: `bool`
    """
    return len(str(a) + str(b) + bar(**kwargs)) > 20

If anyone else is looking for some valid syntax.. Here’s an example docstring. This is just how I did it, I hope it’s useful to you, but I can’t claim that it’s compliant with anything in particular.

def bar(x=True, y=False):
    """
    Just some silly bar function.

    :Parameters:
      - `x` (`bool`) - dummy description for x
      - `y` (`string`) - dummy description for y
    :return: (`string`) concatenation of x and y.
    """
    return str(x) + y

def foo (a, b, **kwargs):
    """
    Do foo on a, b and some other objects.

    :Parameters:
      - `a` (`int`) - A number.
      - `b` (`int`, `string`) - Another number, or maybe a string.
      - `\**kwargs` - remaining keyword arguments are passed to `bar`

    :return: Success
    :rtype: `bool`
    """
    return len(str(a) + str(b) + bar(**kwargs)) > 20

回答 5

这取决于你使用的文档的风格,但如果您使用的是numpydoc风格则建议记录**kwargs使用Other Parameters

例如,遵循quornian的示例:

def some_function(first, second="two", **kwargs):
    """Fetches and returns this thing

    Parameters
    ----------
    first : `int`
        The first parameter
    second : `str`, optional
        The second parameter

    Other Parameters
    ----------------
    extra : `list`, optional
        Extra stuff. Default ``[]``.
    suplement : `dict`, optional
        Additional content. Default ``{'key' : 42}``.
    """

请特别注意,建议提供kwargs的默认值,因为这些默认值在函数签名中并不明显。

This depends on the style of documentation you use, but if you are using the numpydoc style it is recommend to document **kwargs using Other Parameters.

For example, following quornian’s example:

def some_function(first, second="two", **kwargs):
    """Fetches and returns this thing

    Parameters
    ----------
    first : `int`
        The first parameter
    second : `str`, optional
        The second parameter

    Other Parameters
    ----------------
    extra : `list`, optional
        Extra stuff. Default ``[]``.
    suplement : `dict`, optional
        Additional content. Default ``{'key' : 42}``.
    """

Note especially that it is recommended to give the defaults of kwargs, since these are not obvious from the function signature.


回答 6

如果您正在寻找如何以numpydoc样式执行此操作,则可以仅在Parameters部分中提及**kwargs而无需指定类型 -如pandas文档sprint 2018 的sphinx扩展napolean和docstring指南中的numpydoc示例所示

下面是我从发现一个例子的LSST开发人员指南这很好解释了什么是应该是描述**kwargs参数:

def demoFunction(namedArg, *args, flag=False, **kwargs):
    """Demonstrate documentation for additional keyword and
    positional arguments.

    Parameters
    ----------
    namedArg : `str`
        A named argument that is documented like always.
    *args : `str`
        Additional names.

        Notice how the type is singular since the user is expected to pass individual
        `str` arguments, even though the function itself sees ``args`` as an iterable
        of `str` objects).
    flag : `bool`
        A regular keyword argument.
    **kwargs
        Additional keyword arguments passed to `otherApi`.

        Usually kwargs are used to pass parameters to other functions and
        methods. If that is the case, be sure to mention (and link) the
        API or APIs that receive the keyword arguments.

        If kwargs are being used to generate a `dict`, use the description to
        document the use of the keys and the types of the values.
    """

另外,在@Jonas Adler的建议的基础上,我发现最好**kwargs其及其描述放在本Other Parameters节中 -即使是matplotlib文档指南中的示例也表明了这一点

If you are looking for how to do this in numpydoc style, you can simply mention **kwargs in Parameters section without specifying type – as demonstrated in numpydoc example from the sphinx extension napolean and docstring guide from pandas documentation sprint 2018.

Here’s an example I found from LSST developer guide which very well explains what should be the description of **kwargs parameter:

def demoFunction(namedArg, *args, flag=False, **kwargs):
    """Demonstrate documentation for additional keyword and
    positional arguments.

    Parameters
    ----------
    namedArg : `str`
        A named argument that is documented like always.
    *args : `str`
        Additional names.

        Notice how the type is singular since the user is expected to pass individual
        `str` arguments, even though the function itself sees ``args`` as an iterable
        of `str` objects).
    flag : `bool`
        A regular keyword argument.
    **kwargs
        Additional keyword arguments passed to `otherApi`.

        Usually kwargs are used to pass parameters to other functions and
        methods. If that is the case, be sure to mention (and link) the
        API or APIs that receive the keyword arguments.

        If kwargs are being used to generate a `dict`, use the description to
        document the use of the keys and the types of the values.
    """

Alternatively, building upon what @Jonas Adler suggested, I find it better to put the **kwargs and its description in Other Parameters section – even this example from matplotlib documentation guide suggests the same.


Sphinx autodoc不够自动化

问题:Sphinx autodoc不够自动化

我正在尝试使用Sphinx在Python中记录5,000多个项目。它有大约7个基本模块。据我所知,为了使用自动文档,我需要为项目中的每个文件编写如下代码:

.. automodule:: mods.set.tests
    :members:
    :show-inheritance:

这太繁琐了,因为我有很多文件。如果我只想指定要记录的“ mods”包,那会容易得多。然后,Sphinx可以递归地浏览包并为每个子模块创建一个页面。

有这样的功能吗?如果没有,我可以编写一个脚本来制作所有.rst文件,但这将花费很多时间。

I’m trying to use Sphinx to document a 5,000+ line project in Python. It has about 7 base modules. As far as I know, In order to use autodoc I need to write code like this for each file in my project:

.. automodule:: mods.set.tests
    :members:
    :show-inheritance:

This is way too tedious because I have many files. It would be much easier if I could just specify that I wanted the ‘mods’ package to be documented. Sphinx could then recursively go through the package and make a page for each submodule.

Is there a feature like this? If not I could write a script to make all the .rst files, but that would take up a lot of time.


回答 0

您可以检查我编写的脚本。我认为它可以帮助您。

该脚本解析目录树以查找python模块和软件包,并适当地创建ReST文件以使用Sphinx创建代码文档。它还创建一个模块索引。

更新

现在,此脚本作为apidoc是Sphinx 1.1的一部分

You can check this script that I’ve made. I think it can help you.

This script parses a directory tree looking for python modules and packages and creates ReST files appropriately to create code documentation with Sphinx. It also creates a modules index.

UPDATE

This script is now part of Sphinx 1.1 as apidoc.


回答 1

我不知道autosummary在最初提出问题时Sphinx是否具有扩展名,但是现在很可能无需使用sphinx-apidoc类似脚本就可以设置这种自动生成。下面是适用于我的一个项目的设置。

  1. 在文件中启用autosummary扩展名(以及autodocconf.py,并将其autosummary_generate选项设置为True。如果您不使用自定义*.rst模板,这可能就足够了。否则,请添加您的模板目录以排除列表,或者autosummary尝试将它们视为输入文件(这似乎是一个错误)。

    extensions = ['sphinx.ext.autodoc', 'sphinx.ext.autosummary']
    autosummary_generate = True
    templates_path = [ '_templates' ]
    exclude_patterns = ['_build', '_templates']
  2. autosummary::index.rst文件的目录树中使用。在用于模块此示例中的文档project.module1project.module2将自动生成并放入_autosummary目录。

    PROJECT
    =======
    
    .. toctree::
    
    .. autosummary::
       :toctree: _autosummary
    
       project.module1
       project.module2
  3. 默认情况下,autosummary只会为模块及其功能生成非常简短的摘要。要进行更改,可以将自定义模板文件放入_templates/autosummary/module.rst(将使用Jinja2进行解析):

    {{ fullname }}
    {{ underline }}
    
    .. automodule:: {{ fullname }}
        :members:

总之,无需将_autosummary目录保持在版本控制之下。另外,您可以_build随意命名它,并将其放在源代码树中的任何位置(不过,将其放在下面将不起作用)。

I do not know whether Sphinx had had autosummary extension at the time original question was asked, but for now it is quite possible to set up automatic generation of that kind without using sphinx-apidoc or similar script. Below there are settings which work for one of my projects.

  1. Enable autosummary extension (as well as autodoc) in conf.py file and set its autosummary_generate option to True. This may be enough if you’re not using custom *.rst templates. Otherwise add your templates directory to exclude list, or autosummary will try to treat them as input files (which seems to be a bug).

    extensions = ['sphinx.ext.autodoc', 'sphinx.ext.autosummary']
    autosummary_generate = True
    templates_path = [ '_templates' ]
    exclude_patterns = ['_build', '_templates']
    
  2. Use autosummary:: in TOC tree in your index.rst file. In this example documentation for modules project.module1 and project.module2 will be generated automatically and placed into _autosummary directory.

    PROJECT
    =======
    
    .. toctree::
    
    .. autosummary::
       :toctree: _autosummary
    
       project.module1
       project.module2
    
  3. By default autosummary will generate only very short summaries for modules and their functions. To change that you can put a custom template file into _templates/autosummary/module.rst (which will be parsed with Jinja2):

    {{ fullname }}
    {{ underline }}
    
    .. automodule:: {{ fullname }}
        :members:
    

In conclusion, there is no need to keep _autosummary directory under version control. Also, you may name it anything you want and place it anywhere in the source tree (putting it below _build will not work, though).


回答 2

在每个包中,__init__.py文件可以具有.. automodule:: package.module包中每个部分的组件。

然后,您可以.. automodule:: package并且它基本上可以完成您想要的。

In each package, the __init__.py file can have .. automodule:: package.module components for each part of the package.

Then you can .. automodule:: package and it mostly does what you want.


回答 3

从Sphinx 3.1版(2020年6月)开始,sphinx.ext.autosummary(最终!)具有递归功能。

因此,不再需要对模块名称进行硬编码,也无需依赖Sphinx AutoAPISphinx AutoPackageSummary之类的第三方库来进行自动程序包检测。

示例Python 3.7包以进行文档记录(请参阅Github 上的代码ReadTheDocs 上的结果):

mytoolbox
|-- mypackage
|   |-- __init__.py
|   |-- foo.py
|   |-- mysubpackage
|       |-- __init__.py
|       |-- bar.py
|-- doc
|   |-- source
|       |--index.rst
|       |--conf.py
|       |-- _templates
|           |-- custom-module-template.rst
|           |-- custom-class-template.rst

conf.py

import os
import sys
sys.path.insert(0, os.path.abspath('../..'))  # Source code dir relative to this file

extensions = [
    'sphinx.ext.autodoc',  # Core library for html generation from docstrings
    'sphinx.ext.autosummary',  # Create neat summary tables
]
autosummary_generate = True  # Turn on sphinx.ext.autosummary

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

index.rst(请注意新:recursive:选项):

Welcome to My Toolbox
=====================

Some words.

.. autosummary::
   :toctree: _autosummary
   :template: custom-module-template.rst
   :recursive:

   mypackage

这足以自动汇总包中的每个模块,无论它们嵌套得多么深。然后,针对每个模块,汇总该模块中的每个属性,函数,类和异常。

奇怪的是,默认sphinx.ext.autosummary模板不会继续为每个属性,函数,类和异常生成单独的文档页面,并从摘要表链接到它们。可以扩展模板来执行此操作,如下所示,但是我不明白为什么这不是默认行为-当然这是大多数人想要的。我已将其作为功能要求提出

我必须在本地复制默认模板,然后添加到其中:

  • 复制site-packages/sphinx/ext/autosummary/templates/autosummary/module.rstmytoolbox/doc/source/_templates/custom-module-template.rst
  • 复制site-packages/sphinx/ext/autosummary/templates/autosummary/class.rstmytoolbox/doc/source/_templates/custom-class-template.rst

使用该选项,钩子custom-module-template.rst位于index.rst上方:template:。(删除该行以查看使用默认站点程序包模板会发生什么。)

custom-module-template.rst (右侧另加了几行):

{{ fullname | escape | underline}}

.. automodule:: {{ fullname }}
  
   {% block attributes %}
   {% if attributes %}
   .. rubric:: Module Attributes

   .. autosummary::
      :toctree:                                          <-- add this line
   {% for item in attributes %}
      {{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

   {% block functions %}
   {% if functions %}
   .. rubric:: {{ _('Functions') }}

   .. autosummary::
      :toctree:                                          <-- add this line
   {% for item in functions %}
      {{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

   {% block classes %}
   {% if classes %}
   .. rubric:: {{ _('Classes') }}

   .. autosummary::
      :toctree:                                          <-- add this line
      :template: custom-class-template.rst               <-- add this line
   {% for item in classes %}
      {{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

   {% block exceptions %}
   {% if exceptions %}
   .. rubric:: {{ _('Exceptions') }}

   .. autosummary::
      :toctree:                                          <-- add this line
   {% for item in exceptions %}
      {{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

{% block modules %}
{% if modules %}
.. rubric:: Modules

.. autosummary::
   :toctree:
   :template: custom-module-template.rst                 <-- add this line
   :recursive:
{% for item in modules %}
   {{ item }}
{%- endfor %}
{% endif %}
{% endblock %}

custom-class-template.rst (右侧另加了几行):

{{ fullname | escape | underline}}

.. currentmodule:: {{ module }}

.. autoclass:: {{ objname }}
   :members:                                    <-- add at least this line
   :show-inheritance:                           <-- plus I want to show inheritance...
   :inherited-members:                          <-- ...and inherited members too

   {% block methods %}
   .. automethod:: __init__

   {% if methods %}
   .. rubric:: {{ _('Methods') }}

   .. autosummary::
   {% for item in methods %}
      ~{{ name }}.{{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

   {% block attributes %}
   {% if attributes %}
   .. rubric:: {{ _('Attributes') }}

   .. autosummary::
   {% for item in attributes %}
      ~{{ name }}.{{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

From Sphinx version 3.1 (June 2020), sphinx.ext.autosummary (finally!) has recursion.

So no need to hard code module names or rely on 3rd party libraries like Sphinx AutoAPI or Sphinx AutoPackageSummary for their automatic package detection any more.

Example Python 3.7 package to document (see code on Github and result on ReadTheDocs):

mytoolbox
|-- mypackage
|   |-- __init__.py
|   |-- foo.py
|   |-- mysubpackage
|       |-- __init__.py
|       |-- bar.py
|-- doc
|   |-- source
|       |--index.rst
|       |--conf.py
|       |-- _templates
|           |-- custom-module-template.rst
|           |-- custom-class-template.rst

conf.py:

import os
import sys
sys.path.insert(0, os.path.abspath('../..'))  # Source code dir relative to this file

extensions = [
    'sphinx.ext.autodoc',  # Core library for html generation from docstrings
    'sphinx.ext.autosummary',  # Create neat summary tables
]
autosummary_generate = True  # Turn on sphinx.ext.autosummary

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

index.rst (note new :recursive: option):

Welcome to My Toolbox
=====================

Some words.

.. autosummary::
   :toctree: _autosummary
   :template: custom-module-template.rst
   :recursive:

   mypackage

This is sufficient to automatically summarise every module in the package, however deeply nested. For each module, it then summarises every attribute, function, class and exception in that module.

Oddly, though, the default sphinx.ext.autosummary templates don’t go on to generate separate documentation pages for each attribute, function, class and exception, and link to them from the summary tables. It’s possible to extend the templates to do this, as shown below, but I can’t understand why this isn’t the default behaviour – surely that’s what most people would want..? I’ve raised it as a feature request.

I had to copy the default templates locally, and then add to them:

  • Copy site-packages/sphinx/ext/autosummary/templates/autosummary/module.rst to mytoolbox/doc/source/_templates/custom-module-template.rst
  • Copy site-packages/sphinx/ext/autosummary/templates/autosummary/class.rst to mytoolbox/doc/source/_templates/custom-class-template.rst

The hook into custom-module-template.rst is in index.rst above, using the :template: option. (Delete that line to see what happens using the default site-packages templates.)

custom-module-template.rst (additional lines noted on the right):

{{ fullname | escape | underline}}

.. automodule:: {{ fullname }}
  
   {% block attributes %}
   {% if attributes %}
   .. rubric:: Module Attributes

   .. autosummary::
      :toctree:                                          <-- add this line
   {% for item in attributes %}
      {{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

   {% block functions %}
   {% if functions %}
   .. rubric:: {{ _('Functions') }}

   .. autosummary::
      :toctree:                                          <-- add this line
   {% for item in functions %}
      {{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

   {% block classes %}
   {% if classes %}
   .. rubric:: {{ _('Classes') }}

   .. autosummary::
      :toctree:                                          <-- add this line
      :template: custom-class-template.rst               <-- add this line
   {% for item in classes %}
      {{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

   {% block exceptions %}
   {% if exceptions %}
   .. rubric:: {{ _('Exceptions') }}

   .. autosummary::
      :toctree:                                          <-- add this line
   {% for item in exceptions %}
      {{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

{% block modules %}
{% if modules %}
.. rubric:: Modules

.. autosummary::
   :toctree:
   :template: custom-module-template.rst                 <-- add this line
   :recursive:
{% for item in modules %}
   {{ item }}
{%- endfor %}
{% endif %}
{% endblock %}

custom-class-template.rst (additional lines noted on the right):

{{ fullname | escape | underline}}

.. currentmodule:: {{ module }}

.. autoclass:: {{ objname }}
   :members:                                    <-- add at least this line
   :show-inheritance:                           <-- plus I want to show inheritance...
   :inherited-members:                          <-- ...and inherited members too

   {% block methods %}
   .. automethod:: __init__

   {% if methods %}
   .. rubric:: {{ _('Methods') }}

   .. autosummary::
   {% for item in methods %}
      ~{{ name }}.{{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

   {% block attributes %}
   {% if attributes %}
   .. rubric:: {{ _('Attributes') }}

   .. autosummary::
   {% for item in attributes %}
      ~{{ name }}.{{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

回答 4

Sphinx AutoAPI正是这样做的。


回答 5

也许您正在寻找的是Epydoc和此Sphinx扩展

Maybe what you’re looking for is Epydoc and this Sphinx extension.


将Sphinx与Markdown而不是RST一起使用

问题:将Sphinx与Markdown而不是RST一起使用

我讨厌RST,但喜欢狮身人面像。有没有一种方法可以让狮身人面像读取markdown而不是reStructuredText?

I hate RST but love sphinx. Is there a way that sphinx reads markdown instead of reStructuredText?


回答 0

做到这一点的“正确”方法是为降价编写docutils解析器。(加上一个Sphinx选项来选择解析器。)它的优点是可以立即支持所有docutils输出格式(但是您可能并不在意,因为大多数降价工具已经存在)。无需从头开发解析器的方法:

  • 您可以作弊并编写一个“解析器”,该解析器使用Pandoc将markdown转换为RST并将其传递给RST解析器:-)。

  • 您可以使用现有的markdown-> XML解析器,并将结果(使用XSLT?)转换为docutils模式。

  • 您可以使用一些现有的python markdown解析器,使您可以定义自定义渲染器,并使其构建docutils节点树。

  • 您可以分叉现有的RST阅读器,删除与降价无关的所有内容并更改不同的语法(此比较可能会有所帮助)…
    编辑:除非您准备好对其进行大量测试,否则我不建议您使用此路由。Markdown已经有太多不同的方言,这很可能会导致另一方言……

更新: https : //github.com/sgenoud/remarkdown是docutils的降价阅读器。它没有采用上述任何快捷方式,而是使用了受peg-markdown启发的Parsley PEG语法。尚不支持指令。

更新:https : //github.com/rtfd/recommonmark,这是另一个docutils阅读器,ReadTheDocs本身支持。 源自remarkdown,但使用CommonMark-py解析器。不支持指令,但可以将或多或少的自然Markdown语法转换为适当的结构,例如toctree的链接列表。对于其他需求,带```eval_rst围栏的块可让您嵌入任何rST指令。


所有情况下,您都需要发明Markdown的扩展来表示Sphinx指令和角色。虽然您可能不需要全部,但有些.. toctree::是必不可少的。
我认为这是最困难的部分。Sphinx扩展之前的reStructuredText已经比markdown丰富。即使是大幅扩展的降价促销(例如pandoc),也大多是rST功能集的子集。有很多方面需要解决!

在实现方面,最简单的方法是添加泛型构造以表达任何docutils角色/指令。语法启发的显而易见的候选人是:

  • pandoc和其他一些实现已允许在许多内联和块构造中使用属性语法。例如`foo`{.method}-> `foo`:method:
  • HTML / XML。从<span class="method">foo</span>只是插入docutils内部XML的kludgiest方法开始!
  • 某种针对指令的YAML?

但是这样的通用映射不会是最降价十岁上下的解决方案。目前最活跃的地方,讨论降价扩展是https://groups.google.com/forum/#!topic/pandoc-discusshttps://开头github.com/scholmd/scholmd/

这也意味着您不能只使用markdown解析器而不以某种方式扩展它。潘多克(Pandoc)通过支持定制过滤器(fils),再次履行其作为瑞士转换文件的军刀的声誉。(实际上,如果我要采用这种方法,我会尝试在docutils读取器/变压器/编写器与pandoc读取器/过滤器/编写器之间建立通用的桥梁。这超出了您的需求,但收益将远远超过狮身人面像/降价。)


另一个疯狂的主意:扩展reStructuredText而不是扩展markdown来处理Sphinx,以(主要)支持markdown的超集!这样做的好处是,您可以按原样使用任何Sphinx功能,但可以在markdown中编写大多数内容。

已经有相当多的语法重叠 ; 最明显的是链接语法不兼容。我认为,如果您为markdown链接和###-style标头添加了对RST的支持,并将默认`backticks`角色更改为文字,并且可能将缩进的块更改为文字(现在的RST支持> ...引号),那么您将获得支持大多数markdown的有用信息。

The “proper” way to do that would be to write a docutils parser for markdown. (Plus a Sphinx option to choose the parser.) The beauty of this would be instant support for all docutils output formats (but you might not care about that, as similar markdown tools already exist for most). Ways to approach that without developing a parser from scratch:

  1. You could cheat and write a “parser” that uses Pandoc to convert markdown to RST and pass that to the RST parser :-).

  2. You can use an existing markdown->XML parser and transform the result (using XSLT?) to the docutils schema.

  3. You could take some existing python markdown parser that lets you define a custom renderer and make it build docutils node tree.

  4. You could fork the existing RST reader, ripping out everything irrelevant to markdown and changing the different syntaxes (this comparison might help)…
    EDIT: I don’t recommend this route unless you’re prepared to heavily test it. Markdown already has too many subtly different dialects and this will likely result in yet-another-one…

UPDATE: https://github.com/sgenoud/remarkdown is a markdown reader for docutils. It didn’t take any of the above shortcuts but uses a Parsley PEG grammar inspired by peg-markdown.

UPDATE: https://github.com/readthedocs/recommonmark and is another docutils reader, natively supported on ReadTheDocs. Derived from remarkdown but uses the CommonMark-py parser.

  • It can convert specific more-or-less natural Markdown syntaxes to appropriate structures e.g. list of links to a toctree. * Doesn’t have generic native syntax for roles.
  • Supports embedding any rST content, including directives, with an ```eval_rst fenced block as well as a shorthand for directives DIRECTIVE_NAME:: ....

UPDATE: MyST is yet another docutins/Sphinx reader. Based on markdown-it-py, CommonMark compatible.

  • Has a generic {ROLE_NAME}`...` syntax for roles.
  • Has a generic syntax for directives with ```{DIRECTIVE_NAME} ... fenced blocks.

In all cases, you’ll need to invent extensions of Markdown to represent Sphinx directives and roles. While you may not need all of them, some like .. toctree:: are essential.
This I think is the hardest part. reStructuredText before the Sphinx extensions was already richer than markdown. Even heavily extended markdown, such as pandoc’s, is mostly a subset of rST feature set. That’s a lot of ground to cover!

Implementation-wise, the easiest thing is adding a generic construct to express any docutils role/directive. The obvious candidates for syntax inspiration are:

  • Attribute syntax, which pandoc and some other implementations already allow on many inline and block constructs. For example `foo`{.method} -> `foo`:method:.
  • HTML/XML. From <span class="method">foo</span> to the kludgiest approach of just inserting docutils internal XML!
  • Some kind of YAML for directives?

But such a generic mapping will not be the most markdown-ish solution… Currently most active places to discuss markdown extensions are https://groups.google.com/forum/#!topic/pandoc-discuss, https://github.com/scholmd/scholmd/

This also means you can’t just reuse a markdown parser without extending it somehow. Pandoc again lives up to its reputation as the swiss army knife of document conversion by supporting custom filtes. (In fact, if I were to approach this I’d try to build a generic bridge between docutils readers/transformers/writers and pandoc readers/filters/writers. It’s more than you need but the payoff would be much wider than just sphinx/markdown.)


Alternative crazy idea: instead of extending markdown to handle Sphinx, extend reStructuredText to support (mostly) a superset of markdown! The beauty is you’ll be able to use any Sphinx features as-is, yet be able to write most content in markdown.

There is already considerable syntax overlap; most notably link syntax is incompatible. I think if you add support to RST for markdown links, and ###-style headers, and change default `backticks` role to literal, and maybe change indented blocks to mean literal (RST supports > ... for quotations nowdays), you’ll get something usable that supports most markdown.


回答 1

您可以在同一Sphinx项目中使用Markdown和reStructuredText。如何完成此操作,请参见“ 阅读文档”

安装recommonmark(pip install recommonmark),然后编辑conf.py

from recommonmark.parser import CommonMarkParser

source_parsers = {
    '.md': CommonMarkParser,
}

source_suffix = ['.rst', '.md']

我已经在Github上创建了一个小示例项目(serra / sphinx-with-markdown),展示了它的工作原理。它使用CommonMark 0.5.4和recommonmark 0.4.0。

You can use Markdown and reStructuredText in the same Sphinx project. How to do this is succinctly documented on Read The Docs.

Install recommonmark (pip install recommonmark) and then edit conf.py:

from recommonmark.parser import CommonMarkParser

source_parsers = {
    '.md': CommonMarkParser,
}

source_suffix = ['.rst', '.md']

I’ve created a small example project on Github (serra/sphinx-with-markdown) demonstrating how (and that) it works. It uses CommonMark 0.5.4 and recommonmark 0.4.0.


回答 2

它不使用Sphinx,但是MkDocs将使用Markdown构建您的文档。我也讨厌rst,到目前为止,我非常喜欢MkDocs。

This doesn’t use Sphinx, but MkDocs will build your documentation using Markdown. I also hate rst, and have really enjoyed MkDocs so far.


回答 3

更新:现在已正式支持此功能,并在sphinx docs中进行了记录

看起来,基本的实现方式已将其引入Sphinx,但尚未达成共识。查看github问题评论

安装依赖项:

pip install commonmark recommonmark

调整conf.py

source_parsers = {
    '.md': 'recommonmark.parser.CommonMarkParser',
}
source_suffix = ['.rst', '.md']

Update: this is now officially supported and documented in the sphinx docs.

It looks like a basic implementation has made it’s way into Sphinx but word has not gotten round yet. See github issue comment

install dependencies:

pip install commonmark recommonmark

adjust conf.py:

source_parsers = {
    '.md': 'recommonmark.parser.CommonMarkParser',
}
source_suffix = ['.rst', '.md']

回答 4

Markdown和ReST做不同的事情。

RST提供了用于处理文档的对象模型。

Markdown提供了一种雕刻文字的方法。

想要从sphinx项目中引用您的Markdown内容似乎是合理的,使用RST存根整个信息结构和较大文档的流程。让markdown做什么,这使作者可以专注于编写文本。

有没有一种方法可以引用降价域名,仅按原样雕刻内容?RST / sphinx似乎已经照顾好功能,例如toctree没有在markdown中复制它们。

Markdown and ReST do different things.

RST provides an object model for working with documents.

Markdown provides a way to engrave bits of text.

It seems reasonable to want to reference your bits of Markdown content from your sphinx project, using RST to stub out the overall information architecture and flow of a larger document. Let markdown do what it does, which is allow writers to focus on writing text.

Is there a way to reference a markdown domain, just to engrave the content as-is? RST/sphinx seems to have taken care of features like toctree without duplicating them in markdown.


回答 5


回答 6

我同意贝尼(Beni)的建议,将pandoc用于此任务。安装后,以下脚本会将源目录中的所有markdown文件转换为rst文件,以便您可以将所有文档写入markdown中。希望这对其他人有用。

#!/usr/bin/env python
import os
import subprocess

DOCUMENTATION_SOURCE_DIR = 'documentation/source/'
SOURCE_EXTENSION = '.md'
OUTPUT_EXTENSION = '.rst'

for _, __, filenames in os.walk(DOCUMENTATION_SOURCE_DIR):
    for filename in filenames:
        if filename.endswith('.md'):
            filename_stem = filename.split('.')[0]
            source_file = DOCUMENTATION_SOURCE_DIR + filename_stem + SOURCE_EXTENSION
            output_file = DOCUMENTATION_SOURCE_DIR + filename_stem + OUTPUT_EXTENSION
            command = 'pandoc -s {0} -o {1}'.format(source_file, output_file)
            print(command)
            subprocess.call(command.split(' '))

I went with Beni’s suggestion of using pandoc for this task. Once installed the following script will convert all markdown files in the source directory to rst files, so that you can just write all your documentation in markdown. Hope this is useful for others.

#!/usr/bin/env python
import os
import subprocess

DOCUMENTATION_SOURCE_DIR = 'documentation/source/'
SOURCE_EXTENSION = '.md'
OUTPUT_EXTENSION = '.rst'

for _, __, filenames in os.walk(DOCUMENTATION_SOURCE_DIR):
    for filename in filenames:
        if filename.endswith('.md'):
            filename_stem = filename.split('.')[0]
            source_file = DOCUMENTATION_SOURCE_DIR + filename_stem + SOURCE_EXTENSION
            output_file = DOCUMENTATION_SOURCE_DIR + filename_stem + OUTPUT_EXTENSION
            command = 'pandoc -s {0} -o {1}'.format(source_file, output_file)
            print(command)
            subprocess.call(command.split(' '))

回答 7

有一种解决方法。
sphinx-quickstart.py脚本生成一个Makefile。
每次您想要生成文档时,都可以轻松地从Makefile中调用Pandoc,以将Markdown转换为reStructuredText。

There is a workaround.
The sphinx-quickstart.py script generates a Makefile.
You can easily invoke Pandoc from the Makefile every time you’d like to generate the documentation in order to convert Markdown to reStructuredText.


回答 8

这是一个新选项。MyST向Markdown添加了一些功能,这些功能使Sphinx可以像rst一样构建文档。 https://myst-parser.readthedocs.io/en/latest/

Here’s a new option. MyST adds some features to Markdown that allow Sphinx to build docs like rst does. https://myst-parser.readthedocs.io/en/latest/


回答 9

请注意,以下maven插件完全支持使用maven和嵌入式Sphinx + MarkDown支持构建文档:

https://trustin.github.io/sphinx-maven-plugin/index.html

<plugin>
  <groupId>kr.motd.maven</groupId>
  <artifactId>sphinx-maven-plugin</artifactId>
  <version>1.6.1</version>
  <configuration>
    <outputDirectory>${project.build.directory}/docs</outputDirectory>
  </configuration>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>generate</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Note that building documentation using maven and embedded Sphinx + MarkDown support is fully supported by following maven plugin :

https://trustin.github.io/sphinx-maven-plugin/index.html

<plugin>
  <groupId>kr.motd.maven</groupId>
  <artifactId>sphinx-maven-plugin</artifactId>
  <version>1.6.1</version>
  <configuration>
    <outputDirectory>${project.build.directory}/docs</outputDirectory>
  </configuration>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>generate</goal>
      </goals>
    </execution>
  </executions>
</plugin>