¿Cómo documentar un método con parámetro (s)?

139

¿Cómo documentar métodos con parámetros utilizando las cadenas de documentación de Python?

EDITAR: PEP 257 da este ejemplo:

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword arguments:
    real -- the real part (default 0.0)
    imag -- the imaginary part (default 0.0)

    """
    if imag == 0.0 and real == 0.0: return complex_zero
    ...

¿Es esta la convención utilizada por la mayoría de los desarrolladores de Python?

Keyword arguments:
<parameter name> -- Definition (default value if any)

Esperaba algo un poco más formal, como

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    @param: real The real part (default 0.0)
    @param: imag The imaginary part (default 0.0)

    """
    if imag == 0.0 and real == 0.0: return complex_zero
    ...

Entorno : Python 2.7.1

David Andreoletti
fuente
1
¿Has leído PEP 257? python.org/dev/peps/pep-0257
NPE
1
Existen varios 'estándares', pero con un enfoque práctico y especialmente si le gusta algo formal, recomendaría sphinx . Su integración en Pycharm hace que generar cadenas de documentos bien estructuradas sea bastante sencillo. En mi humilde opinión
jojo

Respuestas:

86

Según mi experiencia, las convenciones de docstring numpy (superconjunto PEP257) son las convenciones seguidas más difundidas que también son compatibles con herramientas, como Sphinx .

Un ejemplo:

Parameters
----------
x : type
    Description of parameter `x`.
Vladimir Keleshev
fuente
2
Esto está más cerca de lo que esperaba. Desafortunadamente, elegí PEP 257 simple y agregué mi propia convención (a costa de perder la documentación HTML / PDF autogenerada). Sin embargo, la próxima vez, elegiré esta solución. Gracias.
David Andreoletti
55
Cuando intento procesar su cadena de documentación sugerida, Sphinx se queja SEVERE: Unexpected section title: ¿conoce alguna forma de hacer que Sphinx esté más feliz al respecto?
Brandon Rhodes
@BrandonRhodes este enlace habla sobre el uso de estas convenciones con Sphinx: github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
Vladimir Keleshev
3
En realidad, falta un espacio antes Description. Revisé la documentación vacía, porque inmediatamente me di cuenta y pensé "Espera un segundo, ¿por qué son tres espacios? Eso es extraño. ¿Quién usaría tres espacios?"
Zelphir Kaltstahl
66
Esta puede haber sido la mejor respuesta en el momento en que se hizo la pregunta, pero creo que a partir de ahora (finales de 2017), Sphinx ha salido victorioso.
Alex L
120

Dado que las cadenas de documentos son de forma libre, realmente depende de lo que use para analizar el código para generar la documentación de la API.

Recomendaría familiarizarse con el marcado Sphinx , ya que es ampliamente utilizado y se está convirtiendo en el estándar de facto para documentar proyectos de Python, en parte debido al excelente servicio readthedocs.org . Para parafrasear un ejemplo de la documentación de la esfinge como un fragmento de Python:

def send_message(sender, recipient, message_body, priority=1):
   '''
   Send a message to a recipient

   :param str sender: The person sending the message
   :param str recipient: The recipient of the message
   :param str message_body: The body of the message
   :param priority: The priority of the message, can be a number 1-5
   :type priority: integer or None
   :return: the message id
   :rtype: int
   :raises ValueError: if the message_body exceeds 160 characters
   :raises TypeError: if the message_body is not a basestring
   '''

Este marcado admite referencias cruzadas entre documentos y más. Tenga en cuenta que la documentación de Sphinx usa (p. Ej.), :py:attr:Mientras que solo puede usarlo :attr:cuando documenta desde el código fuente.

Naturalmente, hay otras herramientas para documentar las API. Existe el Doxygen más clásico que usa \param comandos, pero no están diseñados específicamente para documentar el código Python como lo es Sphinx.

Tenga en cuenta que hay una pregunta similar con una respuesta similar aquí ...

anarcat
fuente
9
Este es el estilo utilizado por la autogeneración de comentarios de PyCharm por defecto
Josiah Yoder
¿Qué pasa con la sintaxis de los tipos compuestos como listas de cosas?
matanster
entonces es a list.
anarcat 01 de
33

Convenciones

Herramientas:


Actualización: desde Python 3.5 puede usar sugerencias de tipo, que es una sintaxis compacta y legible por máquina:

from typing import Dict, Union

def foo(i: int, d: Dict[str, Union[str, int]]) -> int:
    """
    Explanation: this function takes two arguments: `i` and `d`.
    `i` is annotated simply as `int`. `d` is a dictionary with `str` keys
    and values that can be either `str` or `int`.

    The return type is `int`.

    """

La principal ventaja de esta sintaxis es que está definida por el lenguaje y que no es ambigua, por lo que herramientas como PyCharm pueden aprovecharla fácilmente.

Jakub Roztocil
fuente
12
Aunque esta respuesta es ahora la más votada, ninguna de las PEP anteriores proporciona una convención para especificar los tipos de argumentos de un método.
koriander
11

Las cadenas de documentos de Python son de forma libre , puede documentarlas de la forma que desee.

Ejemplos:

def mymethod(self, foo, bars):
    """
    Does neat stuff!
    Parameters:
      foo - a foo of type FooType to bar with.
      bars - The list of bars
    """

Ahora, hay algunas convenciones, pero Python no impone ninguna de ellas. Algunos proyectos tienen sus propias convenciones. Algunas herramientas para trabajar con cadenas de documentos también siguen convenciones específicas.

nosklo
fuente
3

La corriente principal es, como ya señalaron otras respuestas aquí, probablemente siguiendo la forma de Sphinx para que pueda usar Sphinx para generar esos documentos elegantes más adelante.

Dicho esto, personalmente voy con el estilo de comentario en línea de vez en cuando.

def complex(  # Form a complex number
        real=0.0,  # the real part (default 0.0)
        imag=0.0  # the imaginary part (default 0.0)
        ):  # Returns a complex number.
    """Form a complex number.

    I may still use the mainstream docstring notation,
    if I foresee a need to use some other tools
    to generate an HTML online doc later
    """
    if imag == 0.0 and real == 0.0:
        return complex_zero
    other_code()

Un ejemplo más aquí, con algunos pequeños detalles documentados en línea:

def foo(  # Note that how I use the parenthesis rather than backslash "\"
          # to natually break the function definition into multiple lines.
        a_very_long_parameter_name,
            # The "inline" text does not really have to be at same line,
            # when your parameter name is very long.
            # Besides, you can use this way to have multiple lines doc too.
            # The one extra level indentation here natually matches the
            # original Python indentation style.
            #
            # This parameter represents blah blah
            # blah blah
            # blah blah
        param_b,  # Some description about parameter B.
            # Some more description about parameter B.
            # As you probably noticed, the vertical alignment of pound sign
            # is less a concern IMHO, as long as your docs are intuitively
            # readable.
        last_param,  # As a side note, you can use an optional comma for
                     # your last parameter, as you can do in multi-line list
                     # or dict declaration.
        ):  # So this ending parenthesis occupying its own line provides a
            # perfect chance to use inline doc to document the return value,
            # despite of its unhappy face appearance. :)
    pass

Los beneficios (como @ mark-horvath ya señaló en otro comentario) son:

  • Lo más importante, los parámetros y su documento siempre permanecen juntos, lo que trae los siguientes beneficios:
  • Menos tipeo (no es necesario repetir el nombre de la variable)
  • Mantenimiento más fácil al cambiar / eliminar variables. Nunca habrá algún párrafo de documento de parámetro huérfano después de cambiar el nombre de algún parámetro.
  • y más fácil de encontrar comentarios faltantes.

Ahora, algunos pueden pensar que este estilo se ve "feo". Pero yo diría que "feo" es una palabra subjetiva. Una forma más neutral es decir que este estilo no es convencional, por lo que puede parecerle menos familiar y, por lo tanto, menos cómodo. Nuevamente, "cómodo" es también una palabra subjetiva. Pero el punto es que todos los beneficios descritos anteriormente son objetivos. No puede lograrlos si sigue el camino estándar.

Esperemos que algún día en el futuro, haya una herramienta de generación de documentos que también pueda consumir ese estilo en línea. Eso impulsará la adopción.

PD: Esta respuesta se deriva de mi preferencia de usar comentarios en línea siempre que lo considero conveniente. También uso el mismo estilo en línea para documentar un diccionario .

RayLuo
fuente
1

Sobre la base de la respuesta de sugerencias de tipo ( https://stackoverflow.com/a/9195565/2418922 ), que proporciona una forma mejor estructurada para documentar tipos de parámetros, también existe una manera estructurada para documentar tanto el tipo como las descripciones de parámetros:

def copy_net(
    infile: (str, 'The name of the file to send'),
    host: (str, 'The host to send the file to'),
    port: (int, 'The port to connect to')):

    pass

ejemplo adoptado de: https://pypi.org/project/autocommand/

DreamFlasher
fuente
1
¿Es esta una sintaxis oficial? Es súper útil, sin embargo, no puedo encontrarlo en los documentos oficiales / PEP ...
Ofri Raviv
1
Me gustaría saber eso también, si hay una PEP para ello.
DreamFlasher
-1

Las cadenas de documentos solo son útiles en entornos interactivos, por ejemplo, el shell de Python. Al documentar objetos que no se van a usar de manera interactiva (por ejemplo, objetos internos, devoluciones de llamada de marco), también podría usar comentarios regulares. Aquí hay un estilo que uso para colgar comentarios sangrados de elementos, cada uno en su propia línea, para que sepa que el comentario se aplica a:

def Recomputate \
  (
    TheRotaryGyrator,
      # the rotary gyrator to operate on
    Computrons,
      # the computrons to perform the recomputation with
    Forthwith,
      # whether to recomputate forthwith or at one's leisure
  ) :
  # recomputates the specified rotary gyrator with
  # the desired computrons.
  ...
#end Recomputate

No puedes hacer este tipo de cosas con cadenas de documentos.

Lawrence D'Oliveiro
fuente
46
Oh, este se ve feo.
Misha Akovantsev
1
Feo si? Idea interesante ... también sí.
David
2
Los comentarios en línea para las variables son muy sensibles, menos tipeo (no es necesario repetir el nombre de la variable), mantenimiento más fácil al cambiar / eliminar la variable ... es más fácil encontrar comentarios faltantes. Lo combinaría con la cadena de documentación adecuada debajo de la firma. +1
Mark Horvath
Eso no funciona como documentación. Si comenta su paquete de esta manera y un usuario de PyCharm lo descarga, no podrá verificar qué hace cada parámetro sin acceder a su documentación, que no podrá generar con ningún software. A menos que hagas el tuyo. Es por eso que OP solicita especificarlo en docstring. Lo siento tan tarde.
Esto es simplemente horrible.
Michael Walters,