Як використовувати autodoc Sphinx для документування методу __init __ (само) класу?


107

Сфінкс за замовчуванням не генерує документи для __init __ (self). Я спробував таке:

.. automodule:: mymodule
    :members:

і

..autoclass:: MyClass
    :members:

У Conf.py, встановивши наведене нижче, додає лише докстринг __init __ (self) до класу docstring (документація на autodoc Sphinx, схоже, погоджується, що це очікувана поведінка, але нічого не згадує щодо проблеми, яку я намагаюся вирішити):

autoclass_content = 'both'

Ні, це не так, як пише сьогодні документація, принаймні: "both" Both the class’ and the __init__ method’s docstring are concatenated and inserted.-> Тому, __init__(self)якщо у вас є , вона повинна бути не тільки доктриною, але і докстрингом класу. Чи можете ви надати тестовий випадок, тому що якщо це так, він відчуває себе помилкою, правда?
lpapp

Відповіді:


116

Ось три варіанти:

  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, як зазначено в коментарі до першого перегляду цієї відповіді).


7
Це не допомагає з автоматичним модулем, оскільки його потрібно додавати до кожного класу.
Роджер Біннс

3
Перша альтернатива спрацювала. У моєму випадку це було краще, ніж друга та третя альтернативи, оскільки не потрібно редагувати .rst файли.
jcarballo

9
У Сфінксі 1.2.1 special-membersпрекрасно працює automodule. Використовувати :special-members: __init__лише для документування __init__.
Флоріан Брюкер

67

Ви були поруч. Ви можете використовувати autoclass_contentопцію у своєму conf.pyфайлі:

autoclass_content = 'both'

1
@MichaelMrozek: Мене теж цікавить це ... Ви зрозуміли високу оцінку цієї відповіді? Спочатку це виглядає як відповідь, яку слід вичистити.
lpapp

1
Я спробував встановити autoclass_content = 'both'параметр, який задокументував метод init , але він показав, що авторезюме з’являється двічі.
Стретч

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


Як це використовувати? Здається, метод повинен бути названий setup(app)для того, щоб виконати Сфінкс.
туш

Я не все це розумію, але дивіться реалізацію xolox, якщо ви хочете розсікати себе. Я вважаю, що він створив розширення сфінкса, яке з'єднує зворотний виклик до події autodoc-skip-member. Коли сфінкс намагається з'ясувати, чи потрібно щось включати / пропускати, ця подія запускається, і його код запускається. Якщо його код виявляє спеціального члена, який був визначений явно користувачем (успадковується, як це часто трапляється), він повідомляє Sphinx включити його. Таким чином, ви можете зробити спеціальних членів, які ви самі пишете
Ендрю

Дякуємо за роз'яснення Андрію, і так, ви правильні морські рибки, потрібна функція налаштування. Я додав це до прикладу, щоб уникнути подальшої плутанини.
xolox

@JoelB: Приклад коду в моєму дописі написаний для того, щоб припустити, що у вашому __init__методі є не порожній docstring . Робить це?
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__'
}

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.