Comment utiliser l'autodoc de Sphinx pour documenter la méthode __init __ (self) d'une classe?

107

Sphinx ne génère pas de documentation pour __init __ (self) par défaut. J'ai essayé ce qui suit:

.. automodule:: mymodule
    :members:

et

..autoclass:: MyClass
    :members:

Dans conf.py, définir ce qui suit n'ajoute que la docstring __init __ (self) à la classe docstring ( la documentation de l'autodoc Sphinx semble convenir qu'il s'agit du comportement attendu, mais ne mentionne rien concernant le problème que j'essaie de résoudre):

autoclass_content = 'both'
Marbre Jacob
la source
Non, ce n'est pas ce que la documentation écrit à ce jour, du moins: "both" Both the class’ and the __init__ method’s docstring are concatenated and inserted.-> Par conséquent, ce ne devrait pas être seulement la __init__(self), mais aussi la classe docstring si vous en avez. Pouvez-vous fournir un cas de test car si c'est le cas, cela ressemble à un bogue, non?
lpapp

Réponses:

116

Voici trois alternatives:

  1. Pour vous assurer que cela __init__()est toujours documenté, vous pouvez utiliser autodoc-skip-memberdans conf.py. Comme ça:

    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)

    Cela définit explicitement de __init__ne pas être ignoré (ce qui est par défaut). Cette configuration est spécifiée une fois et ne nécessite aucun balisage supplémentaire pour chaque classe de la source .rst.

  2. L' special-membersoption a été ajoutée dans Sphinx 1.1 . Cela permet aux membres "spéciaux" (ceux avec des noms comme __special__) d'être documentés par autodoc.

    Depuis Sphinx 1.2, cette option prend des arguments ce qui la rend plus utile qu'elle ne l'était auparavant.

  3. Utilisez automethod:

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

    Ceci doit être ajouté pour chaque classe (ne peut pas être utilisé avec automodule, comme indiqué dans un commentaire à la première révision de cette réponse).

mzjn
la source
7
Cela n'aide pas avec automodule car il doit être ajouté à chaque classe.
Roger Binns
3
La première alternative a fonctionné. Dans mon cas, c'était mieux que les deuxième et troisième alternatives, car il n'a pas besoin d'éditer des fichiers .rst.
jcarballo
9
Dans Sphinx 1.2.1, special-membersfonctionne correctement en utilisant automodule. Utilisez :special-members: __init__uniquement pour documenter __init__.
Florian Brucker
68

Vous étiez proche. Vous pouvez utiliser l' autoclass_contentoption dans votre conf.pyfichier:

autoclass_content = 'both'
gotgenes
la source
1
@MichaelMrozek: Je m'interroge à ce sujet aussi ... Avez-vous compris le taux de vote élevé de cette réponse? Au début, cela ressemble à une réponse qui devrait être purgée.
lpapp
1
J'ai essayé de définir l' autoclass_content = 'both'option, qui a documenté la méthode init , mais cela a fait apparaître le résumé automatique deux fois.
Extrait le
Cela devrait être la réponse acceptée. C'est plus simple et cela fait référence à la documentation officielle du sphinx.
BerriJ le
6

Au cours des dernières années, j'ai écrit plusieurs variantes de autodoc-skip-membercallbacks pour divers projets Python non liés parce que je voulais des méthodes comme __init__(), __enter__()et__exit__() pour apparaître dans ma documentation API (après tout, ces "méthodes spéciales" font partie de l'API et quel meilleur endroit pour les documenter que dans la docstring de la méthode spéciale).

Récemment, j'ai pris la meilleure implémentation et l'ai intégrée à l'un de mes projets Python ( voici la documentation ). La mise en œuvre se résume à ceci:

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

Oui, il y a plus de documentation que de logique :-). L'avantage de définir un autodoc-skip-memberrappel comme celui-ci par rapport à l'utilisation de l' special-membersoption (pour moi) est que l' special-membersoption permet également la documentation de propriétés comme __weakref__(disponible sur toutes les classes de nouveau style, AFAIK) que je considère comme du bruit et pas du tout utiles. L'approche de rappel évite cela (car elle ne fonctionne que sur les fonctions / méthodes et ignore les autres attributs).

xolox
la source
Comment utiliser ceci? Il semble que la méthode doit être nommée setup(app)pour être exécutée par Sphinx.
oarfish
Je ne comprends pas tout, mais voyez l' implémentation de xolox si vous voulez vous disséquer. Je crois qu'il a construit une extension sphinx qui connecte un rappel à l'événement autodoc-skip-member. Lorsque sphinx essaie de déterminer si quelque chose doit être inclus / ignoré, cet événement se déclenche et son code s'exécute. Si son code détecte un membre spécial qui a été défini explicitement par l'utilisateur (hérité comme cela arrive souvent), il dit à Sphinx de l'inclure. De cette façon, vous pouvez documenter les membres spéciaux que vous écrivez vous
Andrew
Merci pour les clarifications Andrew et oui vous avez raison, une fonction de configuration est nécessaire. Je l'ai ajouté à l'exemple pour éviter davantage de confusion.
xolox
@JoelB: L'exemple de code dans mon article est écrit pour supposer que votre __init__méthode a une docstring non vide. Le fait-il?
xolox le
2

Même s'il s'agit d'un article plus ancien, pour ceux qui le recherchent à partir de maintenant, il existe également une autre solution introduite dans la version 1.8. Selon la documentation , vous pouvez ajouter la special-memberclé dans autodoc_default_options à votre fichier conf.py.

Exemple:

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

C'est une variante qui ne comprend que __init__si elle a des 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)
Letmaik
la source