¿Cuál es el formato estándar de cadena de documentos de Python? [cerrado]

888

He visto algunos estilos diferentes de escribir cadenas de documentos en Python, ¿hay un estilo oficial o "acordado"?

Noah McIlraith
fuente
66
python.org/dev/peps/pep-0008 hay una sección completa dedicada a cadenas de documentación
mechanical_meat
30
Creo que esta cuestión no era lo suficientemente claro porque PEP-257 y PEP-8 están el establecimiento sólo la base de las cadenas de documentación, pero ¿qué hay epydoc, doxygen, sphinx? ¿Alguien tiene alguna estadística, es uno de ellos va a reemplazar a los demás, en casos como este, demasiadas opciones pueden dañar.
sorin
1
@sorin, también me gustaría saber qué marcado, si alguno, es más común. Pero creo que la respuesta es que ninguno de ellos es realmente tan común: la gente tiende a preferir mirar la fuente de Python directamente, en lugar de convertirla a html. Por lo tanto, es más útil ser coherente pero optimizado para la legibilidad humana y sin un marcado explícito.
Poolie
3
PyCharm se completa automáticamente de una manera bastante interesante, lo que creo que es una buena implementación de las instrucciones necesarias para ejecutarlo:def foo(self, other):\n\t"""\n\t(blank line)\n\t:param other: \n\t:return:\n\t"""
Matteo Ferla
1
¿Cuál de estas respuestas es la que funciona de manera predeterminada con el analizador de documentación de VS Code?
William Entriken

Respuestas:

1019

Formatos

Las cadenas de documentos de Python se pueden escribir siguiendo varios formatos como mostraron las otras publicaciones. Sin embargo, el formato de cadena de documentación predeterminado de Sphinx no se mencionó y se basa en reStructuredText (reST) . Puede obtener información sobre los formatos principales en esta publicación de blog .

Tenga en cuenta que la PEP 287 recomienda la reST

A continuación se muestran los principales formatos utilizados para las cadenas de documentos.

- Epytext

Históricamente , prevalecía un estilo similar al javadoc , por lo que se tomó como base para Epydoc (con el Epytextformato llamado ) para generar documentación.

Ejemplo:

"""
This is a javadoc style.

@param param1: this is a first param
@param param2: this is a second param
@return: this is a description of what is returned
@raise keyError: raises an exception
"""

- descanso

Hoy en día, el formato probablemente más frecuente es el formato reStructuredText (reST) que Sphinx utiliza para generar documentación. Nota: se usa por defecto en JetBrains PyCharm (escriba comillas triples después de definir un método y presione enter). También se usa de forma predeterminada como formato de salida en Pyment.

Ejemplo:

"""
This is a reST style.

:param param1: this is a first param
:param param2: this is a second param
:returns: this is a description of what is returned
:raises keyError: raises an exception
"""

- Google

Google tiene su propio formato que a menudo se usa. También puede ser interpretado por Sphinx (es decir, utilizando el complemento de Napoleón ).

Ejemplo:

"""
This is an example of Google style.

Args:
    param1: This is the first param.
    param2: This is a second param.

Returns:
    This is a description of what is returned.

Raises:
    KeyError: Raises an exception.
"""

Aún más ejemplos

- Numpydoc

Tenga en cuenta que Numpy recomienda seguir su propio numpydoc basado en el formato de Google y que Sphinx pueda usar.

"""
My numpydoc description of a kind
of very exhautive numpydoc format docstring.

Parameters
----------
first : array_like
    the 1st param name `first`
second :
    the 2nd param
third : {'value', 'other'}, optional
    the 3rd param, by default 'value'

Returns
-------
string
    a value in a string

Raises
------
KeyError
    when a key error
OtherError
    when an other error
"""

Convertir / Generar

Es posible utilizar una herramienta como Pyment para generar automáticamente docstrings a un proyecto de Python aún no documentado, o para convertir docstrings existentes (puede estar mezclando varios formatos) de un formato a otro.

Nota: Los ejemplos se toman de la documentación de pago

daouzli
fuente
10
Podría agregar que reST es lo que se usa por defecto en JetBrains PyCharm, solo escriba comillas triples después de definir su método y presione enter. jetbrains.com/pycharm/help/creating-documentation-comments.html
Felipe Almeida
12
La respuesta más completa incluye un sentido de la historia y las mejores prácticas actuales. Ahora todo lo que necesitamos es un sentido de movimiento de la comunidad hacia un nuevo "mejor" formato y un esfuerzo adicional de la comunidad para crear herramientas de migración de todos los demás al nuevo, para que podamos desarrollar las mejores prácticas.
BobHy
2
yo @daouzli, el enlace de estilo de google es 404. Creo que este es correcto. También puede agregar el ejemplo de estilo esfinge de Google . Gran respuesta por cierto. EDITAR: edité tu respuesta por mí mismo.
voy
44
buena respuesta. Me atrevo a decir dónde puede cambiar el formato predeterminado de docstring en PyCharm (JetBrains): Configuración -> Herramientas -> Herramientas integradas de Python -> Formato Docstring. ¡Buena suerte!
Jackssn
44
Me sorprende que nadie haya comentado sobre la primera línea de texto: actualmente es estrictamente hablando correcto, pero siento que la forma preferida es colocarlo en la primera línea justo después de las comillas triples. PEP 8 y ​​PEP 257 lo hacen en casi todos sus ejemplos. PEP 287 lo hace a su manera, pero en mi experiencia no es tan común.
Lapinot
323

La guía de estilo de Google contiene una excelente guía de estilo de Python. Incluye convenciones para una sintaxis de cadena de documentos legible que ofrece una mejor orientación que PEP-257. Por ejemplo:

def square_root(n):
    """Calculate the square root of a number.

    Args:
        n: the number to get the square root of.
    Returns:
        the square root of n.
    Raises:
        TypeError: if n is not a number.
        ValueError: if n is negative.

    """
    pass

Me gustaría extender esto para incluir también información de tipo en los argumentos, como se describe en este tutorial de documentación de Sphinx . Por ejemplo:

def add_value(self, value):
    """Add a new value.

       Args:
           value (str): the value to add.
    """
    pass
Nathan
fuente
37
El estilo de "firma en cadenas de documentos" me parece muy redundante y detallado. Para Python 3+, las anotaciones de funciones son una forma mucho más limpia de hacer esto. Peor aún si usa tipos pseudo-fuertes: Python es mucho mejor con la escritura de pato.
Evpok
27
Sí, pero al menos da una pista de qué tipo de pato se espera, y la mayoría de los desarrolladores aún no están en Python 3
Anentropic
3
@Evpok personalmente, no me gustan las anotaciones de funciones. Para usar clases en ellas, es posible que tenga que hacer importaciones innecesarias, para usar cadenas en ellas puede quedarse sin espacio horizontal describiéndolas muy rápidamente. Hasta ahora no he visto el punto de usarlos para nada.
OdraEncoded
55
@Nathan, la guía de estilo de Google recomienda comentarios descriptivos en lugar de declarativos, por ejemplo, "Obtener filas de una Bigtable" sobre "Obtener filas de una Bigtable". Por lo tanto, cambiar "Calcular ..." a "Calcula ..." haría que su ejemplo sea más coherente con el resto del comentario, es decir, "Devoluciones" y "Aumentos".
gwg
2
nit: siguiendo el estilo de Google, use una forma descriptiva en lugar de imperativa, es decir, "Calcula ..." y "Agrega ..."
sbeliakov
228

Las convenciones de Docstring están en PEP-257 con mucho más detalle que PEP-8.

Sin embargo, las cadenas de documentos parecen ser mucho más personales que otras áreas de código. Los diferentes proyectos tendrán su propio estándar.

Tiendo a incluir siempre cadenas de documentos, porque tienden a demostrar cómo usar la función y lo que hace muy rápidamente.

Prefiero mantener las cosas consistentes, independientemente de la longitud de la cadena. Me gusta cómo codificar las miradas cuando la sangría y el espaciado son consistentes. Eso significa que uso:

def sq(n):
    """
    Return the square of n. 
    """
    return n * n

Terminado:

def sq(n):
    """Returns the square of n."""
    return n * n

Y tienden a dejar de comentar en la primera línea en cadenas de documentos más largas:

def sq(n):
    """
    Return the square of n, accepting all numeric types:

    >>> sq(10)
    100

    >>> sq(10.434)
    108.86835599999999

    Raises a TypeError when input is invalid:

    >>> sq(4*'435')
    Traceback (most recent call last):
      ...
    TypeError: can't multiply sequence by non-int of type 'str'

    """
    return n*n

Lo que significa que encuentro que las cadenas de documentos que comienzan así son desordenadas.

def sq(n):
    """Return the squared result. 
    ...
Tim McNamara
fuente
90
Tenga en cuenta que PEP-8 dice específicamente que las cadenas de documentos deben escribirse como comandos / instrucciones, en lugar de descripciones, por ejemplo. """Return the squared result"""en lugar de """Returns the squared result""". Aunque personalmente, escribo el mío como Tim está aquí, a pesar de lo que dice la PEP.
Cam Jackson
63
Tampoco estoy de acuerdo con ese consejo (usando el tiempo imperativo) porque comienza a sonar incómodo durante más de una oración. Además, está describiendo una función, sin decirle al lector qué hacer.
mk12
14
Nota: La especificación para cadenas de documentos prescriptivas en lugar de descriptivas realmente aparece en PEP-257 , no en PEP-8. Vengo de una tradición de Java, donde describía funciones, pero finalmente comencé a usar el tiempo imperativo cuando mi paradigma de programación cambió de orientado a objetos a procedimiento. Y cuando comencé a usar pycco para generar documentación de estilo de programación alfabetizada, se hizo muy evidente por qué se sugirió el tiempo imperativo. Debe elegir según su paradigma.
karan.dodia
26
El imperativo es un estado de ánimo gramatical . (Lo siento)
Denis Drescher
55
@ Mk12 Los mensajes de confirmación de Git también deben escribirse como comandos en lugar de descripciones. Y también están " describiendo " un cambio de código, "no diciéndole al lector qué hacer". Así que creo que es solo una convención escribir descripciones como comandos.
onepiece
58

Como aparentemente nadie lo mencionó: también puede usar el Estándar Numpy Docstring . Es ampliamente utilizado en la comunidad científica.

La extensión de la esfinge de Napolean para analizar las cadenas de documentos al estilo de Google (recomendada en la respuesta de @Nathan) también admite la cadena de documentos al estilo Numpy, y hace una breve comparación de ambas.

Y por último un ejemplo básico para dar una idea de cómo se ve:

def func(arg1, arg2):
    """Summary line.

    Extended description of function.

    Parameters
    ----------
    arg1 : int
        Description of arg1
    arg2 : str
        Description of arg2

    Returns
    -------
    bool
        Description of return value

    See Also
    --------
    otherfunc : some related other function

    Examples
    --------
    These are written in doctest format, and should illustrate how to
    use the function.

    >>> a=[1,2,3]
    >>> print [x + 3 for x in a]
    [4, 5, 6]
    """
    return True
joris
fuente
2
El formato NumPy en mi humilde opinión ocupa demasiado espacio vertical, lo cual es escaso en los monitores de pantalla ancha (excepto que usa uno girado 90 grados, pero supongo que la mayoría de la gente no lo hace). Por lo tanto, el formato IMHO de Google es una buena opción con respecto a la legibilidad y las características.
Semanino
3
Supongo que es algo subjetivo. Una vez que tenga una cadena de documentos más compleja (con diferentes secciones, con ejemplos, etc., por lo que, de todos modos, ocupa mucho espacio vertical independientemente del formato), encuentro que el formato numpydoc es más fácil de leer / mejor estructurado.
joris
2
Personalmente, creo que una cadena de documentación tan larga está mejor ubicada en la documentación, no en el código fuente, si es tan larga terminan impidiendo la legibilidad del módulo.
Jonathan Hartley el
12

PEP-8 es el estándar oficial de codificación de python. Contiene una sección sobre cadenas de documentos, que se refiere a PEP-257 , una especificación completa para cadenas de documentos.

bstpierre
fuente
8
Mencionar PEP-257 en el contexto de "cómo debo documentar adecuadamente los parámetros, valores de retorno, excepciones planteadas, etc." es una Broma: no dice una sola palabra sobre ellos (aunque un ejemplo de código muestra algunos). En mi humilde opinión, Google Format es una buena opción en cuanto a legibilidad y características.
Semanino
9

Es Python; todo vale . Considere cómo publicar su documentación . Las cadenas de documentos son invisibles, excepto para los lectores de su código fuente.

A la gente realmente le gusta navegar y buscar documentación en la web. Para lograr eso, use la herramienta de documentación Sphinx . Es el estándar de facto para documentar proyectos de Python. El producto es hermoso: eche un vistazo a https://python-guide.readthedocs.org/en/latest/ . El sitio web Read the Docs alojará sus documentos de forma gratuita.

Coronel Panic
fuente
22
Usualmente uso ipythonpara probar una biblioteca, y hace que la lectura de cadenas de documentos sea muy simple: todo lo que tengo que escribir es your_module.some_method_im_curious_about?y obtengo una impresión agradable, incluida la cadena de documentos.
Thanatos
8
Es probable que los usuarios de una biblioteca o de una API o que están escribiendo un complemento vean el código y necesiten darle sentido. Encuentro comentarios mucho más cruciales en Python que en Java o C # porque los tipos no se declaran. Ayuda mucho si los comentarios dan una idea de qué tipo de patos se pasan y devuelven. (De lo contrario, debe caminar todo el código y calcular que un parámetro dado debe ... ser iterable aquí ... admitir indexación allí ... admitir resta numérica al final ... ¡Ajá! Es básicamente un int array. ¡Un comentario hubiera ayudado!)
Jon Coombs
Eh no. Las cadenas de documentos no son invisibles y ese es un poco el punto. Puede ver la cadena de documentación si ejecuta la helpfunción en la función / método / clase documentada (y eso puede hacerlo incluso si solo tiene acceso al módulo compilado). Personalmente, creo que uno debe tener esto en cuenta al elegir la convención de docstring (es decir, que tiene la intención de leerse tal cual).
Skyking
7

Sugiero usar el programa pep257 Python de Vladimir Keleshev para verificar sus cadenas de documentos con PEP-257 y el Estándar de Numpy Docstring para describir parámetros, devoluciones, etc.

pep257 informará la divergencia que realice del estándar y se llama pylint y pep8.

Finn Årup Nielsen
fuente
Mencionar PEP-257 en el contexto de "cómo debo documentar adecuadamente los parámetros, valores de retorno, excepciones planteadas, etc." es una Broma: no dice una sola palabra sobre ellos (aunque un ejemplo de código muestra algunos). El formato NumPy en mi humilde opinión ocupa demasiado espacio vertical, que es escaso en los monitores de pantalla ancha (excepto que usas uno girado 90 grados, pero supongo que la mayoría de la gente no lo hace). Entonces, el formato Google de mi humilde opinión es una buena opción en cuanto a legibilidad y características.
Semanino
1
@Semanino Menciono el Estándar Numpy Docstring en el contexto del programa pep257, no PEP-257. Ese programa ahora se llama pydocstyle. pydocstyle le permite hacer algunas comprobaciones de numpydoc, por ejemplo, pydocstyle --select=D4 tmp.pycomprobaciones de una variedad de problemas de contenido de docstring, incluida la denominación de secciones.
Finn Årup Nielsen