Guía Completa de Docstring en Python: Estilo, PEP 257, Doctest y Mejores Prácticas

1. ¿Qué es un docstring en Python?

En Python, un docstring es una cadena especial que se utiliza para añadir descripciones a funciones, clases o módulos. Los docstring mejoran la mantenibilidad del código y facilitan la comprensión para otros desarrolladores. Además, mediante herramientas de generación automática de documentación (ejemplo: Sphinx), es posible crear documentación basada en los docstring.

Ubicación y formato de un docstring

Un docstring se coloca inmediatamente después de la definición de una función, clase o módulo, y suele estar delimitado por comillas triples dobles. La sintaxis típica es la siguiente:
def nombre_funcion(argumentos):
    """
    Aquí se escribe una breve descripción de la función.

    Argumentos:
        nombre (tipo): Descripción detallada del argumento
    Retorna:
        tipo: Descripción del valor de retorno
    """
    pass
El docstring se utiliza en la función incorporada help() de Python y en las ayudas de los editores, desempeñando un papel fundamental como documentación del código.

2. Escritura básica de un docstring

Un docstring en Python se emplea para describir de forma clara y concisa la especificación de una función o clase. Generalmente comienza con un resumen breve del propósito de la función, seguido de detalles sobre los argumentos, valores de retorno o errores posibles. Siguiendo la guía oficial PEP 257, se garantiza consistencia y legibilidad para otros desarrolladores.

Estructura básica de un docstring

Un docstring de una sola línea se utiliza para descripciones muy breves, como en el siguiente ejemplo:
def add(a, b):
    """Suma dos números y devuelve el resultado."""
    return a + b
Un docstring multilínea se usa cuando se requiere mayor detalle, explicando argumentos y valores de retorno con saltos de línea para mejorar la legibilidad.
def add(a, b):
    """
    Suma dos números y devuelve el resultado.

    Argumentos:
        a (int): El primer número a sumar
        b (int): El segundo número a sumar

    Retorna:
        int: La suma de los dos números
    """
    return a + b
侍エンジニア塾

3. Estilos de docstring (Google, NumPy, reStructuredText)

Existen diferentes estilos de docstring según el proyecto o la herramienta utilizada. Los más comunes son: Google, NumPy y reStructuredText.

Estilo Google

El estilo Google se caracteriza por su claridad y simplicidad. Los argumentos y valores de retorno se organizan en secciones como Args y Returns.
def add(a, b):
    """
    Suma dos números y devuelve el resultado.

    Args:
        a (int): El primer número
        b (int): El segundo número

    Returns:
        int: La suma de los dos números
    """
    return a + b

Estilo NumPy

El estilo NumPy proporciona un formato más detallado, muy utilizado en bibliotecas científicas y de análisis de datos. Usa secciones como Parameters y Returns.
def add(a, b):
    """
    Suma dos números y devuelve el resultado.

    Parameters
    ----------
    a : int
        El primer número
    b : int
        El segundo número

    Returns
    -------
    int
        La suma de los dos números
    """
    return a + b

Estilo reStructuredText

El estilo reStructuredText es usado en herramientas como Sphinx para generar documentación automática en HTML o PDF.
def add(a, b):
    """
    Suma dos números.

    :param a: El primer número
    :type a: int
    :param b: El segundo número
    :type b: int
    :return: La suma de los dos números
    :rtype: int
    """
    return a + b

4. PEP 257 y mejores prácticas

PEP 257 es la guía oficial para la escritura de docstring en Python. Seguirla mejora la legibilidad y consistencia del código.

Puntos clave de PEP 257

  1. Docstring de una línea: Para funciones simples, se recomienda una breve descripción en una sola línea.
  2. Docstring multilínea: Cuando se requiere más detalle, se comienza con un resumen, seguido de una línea en blanco y la explicación extendida.
  3. Indentación y saltos de línea: Se recomienda usar saltos y sangrías para mayor claridad.

Mejores prácticas

  • Claridad y precisión: El docstring debe ser conciso pero transmitir exactamente lo que hace la función o clase.
  • Estilo consistente: Mantener un mismo estilo en todo el proyecto (Google, NumPy, etc.) mejora la coherencia.

5. Pruebas con docstring (doctest)

Python incluye el módulo doctest, que permite verificar si los ejemplos de código incluidos en un docstring funcionan realmente como se espera. Gracias a esto, los ejemplos en la documentación se convierten en pruebas automáticas que mejoran la confiabilidad del código.

Uso básico de doctest

doctest detecta automáticamente el código dentro de un docstring y valida que la salida coincida con lo descrito. Por ejemplo:
def add(a, b):
    """
    Suma dos números y devuelve el resultado.

    Args:
        a (int): Primer número
        b (int): Segundo número

    Returns:
        int: La suma de los dos números

    Example:
        >>> add(2, 3)
        5
        >>> add(0, 0)
        0
    """
    return a + b

if __name__ == "__main__":
    import doctest
    doctest.testmod()
En este ejemplo, doctest ejecuta los ejemplos dentro del docstring y compara los resultados. Si las pruebas pasan, no se muestra nada; si fallan, aparece un mensaje de error. Así se asegura que los ejemplos siempre sean correctos.

Ventajas de usar doctest

  1. Consistencia: Garantiza que el código en los docstring coincida con el comportamiento real de la función.
  2. Automatización: Permite validar múltiples ejemplos de forma automática sin escribir pruebas adicionales.

6. Ejemplo práctico: Documentación con docstring

El uso de docstring mejora notablemente la legibilidad del código y facilita el trabajo en equipo. A continuación, un ejemplo de cómo documentar una clase en Python y luego generar documentación automáticamente con Sphinx.

Ejemplo de docstring en una clase

class Calculator:
    """
    Clase sencilla de calculadora.

    Ofrece operaciones básicas de suma, resta, multiplicación y división.

    Attributes:
        result (int): Almacena el último resultado
    """

    def __init__(self):
        """
        Constructor de la clase Calculator.
        Inicializa el resultado en 0.
        """
        self.result = 0

    def add(self, a, b):
        """
        Suma dos números y devuelve el resultado.

        Args:
            a (int): Primer número
            b (int): Segundo número

        Returns:
            int: La suma de los dos números
        """
        self.result = a + b
        return self.result
En este caso, la clase y cada método contienen su propio docstring, lo que permite a otros desarrolladores entender rápidamente su funcionamiento.

Generación de documentación con Sphinx

Sphinx puede generar automáticamente documentación en HTML o PDF a partir de los docstring. Primero, se instala con:
pip install sphinx
Luego se inicializa el proyecto con:
sphinx-quickstart
Finalmente, con el comando:
make html
se genera la documentación en HTML a partir de los docstring.

7. Errores comunes y cómo evitarlos

Al escribir docstring, los principiantes suelen cometer errores frecuentes. Aquí algunos de los más comunes:

1. Explicaciones vagas

Un docstring debe ser claro y preciso. Ejemplo de mala práctica:
def add(a, b):
    """Suma dos números."""
    return a + b
Falta especificar tipos de argumentos y valor de retorno. Mejor versión:
def add(a, b):
    """
    Suma dos enteros y devuelve el resultado.

    Args:
        a (int): Primer número
        b (int): Segundo número

    Returns:
        int: La suma de los dos enteros
    """
    return a + b

2. Falta de detalles en argumentos o retornos

Si no se describen bien los argumentos, el usuario puede malinterpretar la función. Ejemplo incorrecto:
def divide(a, b):
    """Divide dos números."""
    return a / b
Mejor versión:
def divide(a, b):
    """
    Divide dos números y devuelve el resultado.  
    Lanza ZeroDivisionError si el divisor es 0.

    Args:
        a (float): Número dividendo
        b (float): Número divisor

    Returns:
        float: Resultado de la división

    Raises:
        ZeroDivisionError: Si b es 0
    """
    if b == 0:
        raise ZeroDivisionError("No se puede dividir entre 0")
    return a / b

8. Conclusión: Documentación eficiente con docstring

En este artículo hemos visto qué es un docstring, cómo escribirlo, los estilos más usados, las guías de PEP 257 y su integración con doctest y Sphinx. Los docstring aumentan la legibilidad y mantenibilidad del código, a la vez que permiten pruebas y generación automática de documentación.

PEP 257 como guía

Seguir PEP 257 asegura documentación clara, consistente y fácil de leer.

Pruebas con doctest

Permite comprobar automáticamente que los ejemplos de los docstring funcionan correctamente.

Automatización con Sphinx

Con Sphinx, la documentación siempre estará actualizada con el código más reciente, sin necesidad de escribir manualmente cada detalle.
年収訴求