Как использовать автодок Sphinx для документирования метода __init __ (self) класса?

108

По умолчанию Sphinx не создает документы для __init __ (self). Я пробовал следующее:

.. automodule:: mymodule
    :members:

и

..autoclass:: MyClass
    :members:

В conf.py установка следующего только добавляет строку документации __init __ (self) в строку документации класса ( документация Sphinx autodoc, похоже, согласна с тем, что это ожидаемое поведение, но ничего не упоминает о проблеме, которую я пытаюсь решить):

autoclass_content = 'both'
Джейкоб Марбл
источник
Нет, это не то, что написано в документации на сегодняшний день, по крайней мере: "both" Both the class’ and the __init__ method’s docstring are concatenated and inserted.-> Следовательно, это должна быть не только __init__(self)строка документации класса, если она у вас есть. Можете ли вы предоставить тестовый пример, потому что если это так, это похоже на ошибку, верно?
lpapp

Ответы:

117

Вот три альтернативы:

  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Вариант был добавлен в Сфинкса 1.1 . Он позволяет документировать "специальные" члены (с такими именами __special__) в autodoc.

    Начиная с Sphinx 1.2, эта опция принимает аргументы, что делает ее более полезной, чем раньше.

  3. Использование automethod:

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

    Это должно быть добавлено для каждого класса (не может использоваться automodule, как указано в комментарии к первой редакции этого ответа).

mzjn
источник
7
Это не помогает с автоматическим планированием, поскольку его нужно добавлять в каждый класс.
Роджер Биннс,
3
Первая альтернатива сработала. В моем случае это было лучше, чем вторая и третья альтернативы, так как не нужно было редактировать файлы .rst.
jcarballo
9
В Sphinx 1.2.1 special-membersотлично работает с использованием automodule. Используйте :special-members: __init__только для документирования __init__.
Флориан Брукер,
68

Вы были близки. Вы можете использовать autoclass_contentопцию в своем conf.pyфайле:

autoclass_content = 'both'
gotgenes
источник
1
@MichaelMrozek: Меня это тоже интересует ... Вы понимаете, насколько высокий процент положительных голосов за этот ответ? Сначала это похоже на ответ, который следует очистить.
lpapp 08
1
Я попытался установить autoclass_content = 'both'опцию, которая документировала метод инициализации , но из-за этого автосводка появлялась дважды.
Stretch
Это должен быть принятый ответ. Это проще и ссылается на официальную документацию по сфинксу.
BerriJ
6

За последние годы я написал несколько вариантов 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), которые я считаю шумными и совершенно бесполезными. Подход обратного вызова позволяет избежать этого (поскольку он работает только с функциями / методами и игнорирует другие атрибуты).

xolox
источник
Как мне это использовать? Кажется, что метод должен быть назван setup(app), чтобы его мог выполнить Sphinx.
oarfish
Я не понимаю всего этого, но посмотрите на реализацию xolox, если хотите препарировать себя. Я считаю, что он создал расширение sphinx, которое соединяет обратный вызов с событием autodoc-skip-member. Когда сфинкс пытается выяснить, нужно ли что-то включать / пропускать, это событие срабатывает, и его код запускается. Если его код обнаруживает специальный член, который был явно определен пользователем (унаследованный, как это часто бывает), он сообщает Sphinx, чтобы он включил его. Таким образом, вы можете документировать специальных участников, которых вы пишете сами
Эндрю
Спасибо за разъяснения, Эндрю, и да, вы правы, oarfish, нужна функция настройки. Я добавил его в пример, чтобы избежать путаницы.
xolox
@JoelB: Пример кода в моем сообщении написан для предположения, что ваш __init__метод имеет непустую строку документации. Является ли?
xolox
2

Несмотря на то, что это более старый пост, для тех, кто ищет его сейчас, есть еще одно решение, представленное в версии 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__'
}
dheinz
источник
0

Это вариант, который включает только в том __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)
Letmaik
источник