Cuántos argumentos debe tener una función en Python
Una de las señales más claras de que una función está haciendo demasiado es que tiene demasiados argumentos. Cuando hay muchos argumentos se vuelve el código difícil de leer, testear y documentar. ¿Cual es el límite?
Una regla sencilla que funciona bien en la práctica:
- Ideal: De 0 a 2 argumentos.
- Aceptable: De 3 o 4 (si están bien justificados o usan valores por defecto).
- Mal diseño: De 5 al infinito.
Pero hay funciones que necesito añadir más argumentos, por ejemplo a la hora de crear un usuario, necesito nombre, apellido, email, teléfono, dirección... Debe existir una solución para esto sin romper la regla de los 4 argumentos.
Pues yo te propongo algunas herramientas, y ya decides tú cuál encaja mejor en tu caso.
Dataclasses
Si tienes varios argumentos relacionados, agrúpalos en un dataclass. La función recibe un único objeto con todo lo necesario.
from dataclasses import dataclass
@dataclass
class Direccion:
"""Dirección postal completa de un usuario.
Attributes:
calle: Nombre de la calle y número.
ciudad: Ciudad de residencia.
codigo_postal: Código postal de la zona.
"""
calle: str
ciudad: str
codigo_postal: str
def crear_usuario(
nombre: str, apellido: str, email: str, telefono: str, direccion: Direccion
) -> None:
"""Crea un nuevo usuario en el sistema.
Args:
nombre: Nombre de pila del usuario.
apellido: Primer apellido.
email: Dirección de correo electrónico.
telefono: Número de teléfono de contacto.
direccion: Dirección postal completa.
"""
# Tu lógica aquí
Argumentos con nombre obligatorio
El * en la firma fuerza a que todo lo que viene después se pase con nombre. Su ventaja principal es que mejora la legibilidad, ya que el código que llama a la función es más explícito.
def configurar_grafico(
titulo: str,
*,
ancho: int = 800,
alto: int = 600,
color_linea: str = "azul",
grosor: int = 2,
) -> None:
"""Configura y renderiza un gráfico.
Args:
titulo: Título del gráfico.
ancho: Ancho en píxeles, por defecto 800.
alto: Alto en píxeles, por defecto 600.
color_linea: Color de la línea principal, por defecto "azul".
grosor: Grosor de la línea en puntos, por defecto 2.
"""
pass
configurar_grafico("Mi Gráfico", ancho=1024, color_linea="rojo")
Validación con msgspec
Trabajar con alguna biblioteca de validación de datos, por ejemplo msgspec. Si has trabajado con pydantic, te sentirás muy cómodo. Podríamos considerar msgspec un validador y parseador moderno, ligero (escrito en C) y muy eficiente.
import msgspec
class Usuario(msgspec.Struct, strict=True):
"""Modelo de usuario con validación estricta de tipos.
Attributes:
nombre: Nombre completo del usuario.
edad: Edad en años.
"""
nombre: str
edad: int
datos_entrada = {"nombre": "Ana", "edad": 28}
usuario_validado = msgspec.convert(datos_entrada, type=Usuario)
Con strict=True, si el tipo no coincide exactamente, lanza un error. Sin sorpresas.
Apuntes finales
No he incluido *args y **kwargs porque solo esconden los argumentos. Son útiles en contextos concretos (decoradores, wrappers, APIs muy genéricas), pero no son una excusa para no pensar en el diseño.
Espero que ahora antes de añadir un quinto argumento, pregúntate si realmente pertenece ahí o si es una señal de que la función asume demasiadas responsabilidades.
Este trabajo está bajo una licencia Attribution-NonCommercial-NoDerivatives 4.0 International.
Apóyame en Ko-fi
Comentarios
Todavía no hay ningún comentario.