ProgramaciónDesarrollador Python

Explique cómo funcionan los argumentos *args y **kwargs en las funciones de Python. ¿Para qué se utilizan, qué peligros tienen si se aplican incorrectamente y cómo combinarlos correctamente con argumentos posicionales y nombrados?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

*args — recopila una cantidad arbitraria de argumentos posicionales en una tupla.

**kwargs — recopila una cantidad arbitraria de argumentos nombrados (clave=valor) en un diccionario.

Esto permite escribir funciones con una interfaz flexible:

def my_func(a, b, *args, **kwargs): print(a, b) print(args) print(kwargs) my_func(1, 2, 3, 4, x=10, y=20) # 1 2 # (3, 4) # {'x': 10, 'y': 20}

Detalles:

  • Los argumentos comunes deben ir primero, luego *args, después los nombrados con valores por defecto, y **kwargs — estrictamente en ese orden al declarar la función.
  • A través de * se pueden "desempaquetar" secuencias, y a través de ** — diccionarios al llamar a la función.
  • No se pueden volver a definir los mismos parámetros — esto generará un error TypeError.

Pregunta trampa

¿Se puede cambiar el orden de *args y los argumentos nombrados con valor por defecto, por ejemplo:

def foo(a, *args, x=10, **kwargs): pass

¿o necesariamente siempre deben colocarse los valores por defecto después de *args?

Respuesta:

¡En Python 3 se puede! Así (no funcionaba en Python 2):

def foo(a, *args, x=10): pass

Los parámetros después de *args ("argumentos solo por palabra clave") pueden tener valores por defecto o ser obligatorios — solo se pueden especificar por nombre.

Ejemplos de errores reales debido a la falta de conocimiento sobre los detalles del tema


Historia

Pasar argumentos incorrectos a través de *args/**kwargs

En servicios REST API, la automatización del marshalling de datos se construyó a través de **kwargs. Un parámetro adicional no fue notado — la función aceptó un valor inesperado en kwargs, lo que llevó a la pérdida de lógica de control y errores difíciles de depurar.


Historia

Duplicación de argumentos nombrados

Al llamar a la función, el desarrollador accidentalmente especificó un parámetro tanto de forma explícita como a través de **kwargs, por ejemplo: my_func(a=1, **{"a": 2}). Como resultado — TypeError y caída del servicio.


Historia

Olvidaron argumentos posicionales o solo nombrados

Al escribir un decorador, la transmisión incorrecta de parámetros (no se cumplió el orden y la estructura) llevó a que la función original recibiera un número incorrecto de argumentos, cuyos acuerdos cambiaron, y en producción comenzaron a surgir errores de llamada TypeError.