Ir al contenido principal

Documentación de código: docstrings

Introducción

La documentación es un componente esencial en el desarrollo de software que permite a los programadores entender cómo funciona el código y cómo utilizarlo correctamente. En Python, los docstrings son la forma estándar de documentar módulos, clases, métodos y funciones. A diferencia de los comentarios habituales, los docstrings son cadenas de texto especiales que están asociadas con componentes del código y son accesibles en tiempo de ejecución. En este artículo, aprenderás a escribir docstrings efectivos siguiendo las convenciones de Python para crear código más mantenible y accesible.

¿Qué son los docstrings?

Los docstrings son cadenas de documentación que se colocan como primera instrucción en un módulo, función, clase o método. Se definen usando tres comillas simples (''') o tres comillas dobles (""").

def suma(a, b):
    """
    Suma dos números y devuelve el resultado.
    
    Args:
        a: Primer número a sumar
        b: Segundo número a sumar
        
    Returns:
        La suma de a y b
    """
    return a + b

Características de los docstrings

  • Se conservan como parte del objeto documentado durante la ejecución
  • Son accesibles mediante el atributo __doc__ o la función help()
  • Deben estar correctamente indentados
  • La primera línea debe ser un resumen conciso
  • Si hay más líneas, debe haber una línea en blanco después del resumen

Accediendo a los docstrings

Puedes acceder a los docstrings de varias formas:

# Usando el atributo __doc__
print(suma.__doc__)

# Usando la función help
help(suma)

Estilos de docstrings

Existen varios estilos establecidos para escribir docstrings en Python:

Estilo Google

def dividir(a, b):
    """Divide dos números y devuelve el resultado.
    
    Args:
        a (float): Numerador
        b (float): Denominador, no puede ser cero
        
    Returns:
        float: El resultado de la división a/b
        
    Raises:
        ValueError: Si b es cero
    
    Examples:
        >>> dividir(10, 2)
        5.0
    """
    if b == 0:
        raise ValueError("El denominador no puede ser cero")
    return a / b

Estilo reStructuredText (reST)

def dividir(a, b):
    """Divide dos números y devuelve el resultado.
    
    :param a: Numerador
    :type a: float
    :param b: Denominador, no puede ser cero
    :type b: float
    :returns: El resultado de la división a/b
    :rtype: float
    :raises ValueError: Si b es cero
    
    .. code-block:: python
    
        >>> dividir(10, 2)
        5.0
    """
    if b == 0:
        raise ValueError("El denominador no puede ser cero")
    return a / b

Estilo NumPy/SciPy

def dividir(a, b):
    """Divide dos números y devuelve el resultado.
    
    Parameters
    ----------
    a : float
        Numerador
    b : float
        Denominador, no puede ser cero
        
    Returns
    -------
    float
        El resultado de la división a/b
        
    Raises
    ------
    ValueError
        Si b es cero
        
    Examples
    --------
    >>> dividir(10, 2)
    5.0
    """
    if b == 0:
        raise ValueError("El denominador no puede ser cero")
    return a / b

Docstrings para diferentes componentes

Docstrings para módulos

Se colocan al principio del archivo:

"""
Este módulo proporciona funciones para operaciones matemáticas básicas.

Incluye operaciones como suma, resta, multiplicación y división.
También maneja errores comunes como división por cero.
"""

# Resto del código del módulo...

Docstrings para clases

class Calculadora:
    """
    Clase que realiza operaciones matemáticas básicas.
    
    Esta clase proporciona métodos para sumar, restar, multiplicar
    y dividir números.
    
    Attributes:
        historial (list): Lista que almacena las operaciones realizadas
    """
    
    def __init__(self):
        """Inicializa una nueva calculadora con historial vacío."""
        self.historial = []

Docstrings para métodos

def sumar(self, a, b):
    """
    Suma dos números y guarda la operación en el historial.
    
    Args:
        a (float): Primer número
        b (float): Segundo número
        
    Returns:
        float: Resultado de la suma
    """
    resultado = a + b
    self.historial.append(f"{a} + {b} = {resultado}")
    return resultado

Documentando propiedades especiales

Documentando parámetros opcionales

def conectar_bd(host, puerto=3306, usuario="admin"):
    """
    Establece conexión con una base de datos.
    
    Args:
        host (str): Dirección del servidor de la base de datos
        puerto (int, opcional): Puerto de conexión. Por defecto es 3306
        usuario (str, opcional): Nombre de usuario. Por defecto es "admin"
        
    Returns:
        Connection: Objeto de conexión a la base de datos
    """
    # Código de conexión...

Documentando funciones con *args y **kwargs

def concatenar(*args, separador=" "):
    """
    Concatena cadenas de texto con un separador opcional.
    
    Args:
        *args: Cadenas de texto a concatenar
        separador (str, opcional): Carácter o texto para separar.
            Por defecto es un espacio.
            
    Returns:
        str: Texto concatenado
    """
    return separador.join(str(arg) for arg in args)

Herramientas para los docstrings

Sphinx

Sphinx es un generador de documentación que puede crear documentación en diversos formatos (HTML, PDF, etc.) a partir de los docstrings de tu código:

# Instalar Sphinx
pip install sphinx

# Iniciar un proyecto de documentación
sphinx-quickstart

# Generar documentación
sphinx-build -b html source_dir build_dir

pydoc

La biblioteca estándar pydoc permite generar documentación a partir de docstrings:

# Ver documentación en la terminal
python -m pydoc nombre_modulo

# Generar documentación HTML
python -m pydoc -w nombre_modulo

Buenas prácticas

  1. Consistencia: Elige un estilo de docstring y úsalo en todo el proyecto
  2. Concisión: El resumen inicial debe ser breve y claro
  3. Completitud: Documenta todos los parámetros, valores de retorno y excepciones
  4. Ejemplos: Incluye ejemplos de uso siempre que sea posible
  5. Actualización: Mantén la documentación sincronizada con los cambios en el código
  6. No repitas el código: Los docstrings deben complementar el código, no repetirlo
  7. Especificidad: Documenta los tipos de datos esperados y devueltos

Verificación automática de docstrings

Existen herramientas que pueden verificar la calidad de tus docstrings:

# Instalar pylint para verificar la presencia de docstrings
pip install pylint

# Ejecutar pylint
pylint --disable=all --enable=missing-docstring tu_archivo.py

# Instalar pydocstyle para verificar el estilo de los docstrings
pip install pydocstyle

# Ejecutar pydocstyle
pydocstyle tu_archivo.py

Docstrings en la línea de comandos interactiva

Los docstrings son especialmente útiles en la línea de comandos interactiva de Python:

>>> import math
>>> help(math.sqrt)
Help on built-in function sqrt in module math:

sqrt(x, /)
    Return the square root of x.

Resumen

Los docstrings son una herramienta fundamental en Python para documentar el código de manera estructurada. Siguiendo las convenciones establecidas y adoptando buenas prácticas, puedes crear documentación clara y accesible que facilite el uso y mantenimiento de tu código. Los docstrings no solo ayudan a otros desarrolladores a entender tu código, sino que también pueden servir como base para generar documentación más elaborada utilizando herramientas como Sphinx. Invierte tiempo en escribir buenos docstrings y tu futuro yo (y cualquier otra persona que use tu código) te lo agradecerá. En el siguiente artículo, exploraremos técnicas de rendimiento y optimización para hacer que nuestro código Python sea más eficiente.