如何使用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)