ProgramaciónDesarrollador Backend

¿Cómo funciona el mecanismo de manejo de argumentos posicionales y por palabras clave (positional and keyword arguments) en Python? ¿Cuáles son las sutilezas del orden de los argumentos al definir una función y al llamarla, y para qué son necesarios los parámetros solo posicionales y solo nombrados?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

En Python, se pueden declarar cuatro tipos de parámetros en una función: posicionales, por palabra clave (keyword), solo posicionales (positional-only) y solo nombrados (keyword-only). Su diferencia influye en la forma de pasar valores al llamar a la función.

Tipos de parámetros

  1. Posicionales (generalmente van primero): los valores se pasan en el orden indicado.
  2. Por palabra clave: se especifican explícitamente por nombre.
  3. Solo posicionales: se declaran antes del símbolo / (Python 3.8+), no se pueden pasar por nombre.
  4. Solo nombrados: se declaran después de *, se pueden pasar solo por clave.
# Ejemplo de todos los tipos def func(a, b, /, c, *, d, e): print(a, b, c, d, e) func(1, 2, 3, d=4, e=5) # OK # func(a=1, b=2, 3, d=4, e=5) # Error: a, b - solo posicionales

Sutilezas

  • Orden de los parámetros: (solo-posicional) / (posicional-o-por-palabra) * (solo-nombrado)
  • Con un orden erróneo de los argumentos — SyntaxError o TypeError.
  • *args recoge posicionales adicionales; **kwargs — por nombre.

Pregunta con trampa.

¿Cuáles son las diferencias en las declaraciones de funciones:

def f(a, b, c): ... def f(a, b, c=1): ... def f(a, b=1, c=2): ... def f(a=1, b=2, c=3): ...

¿y es verdad que todas estas funciones se pueden llamar utilizando tanto argumentos posicionales como por palabra clave?

Respuesta:

  • Para la función def f(a, b, c): no se puede llamar solo con argumentos por clave, porque se puede pasar todo tanto por posición como por clave, pero todos los argumentos son obligatorios.
  • Se pueden especificar parámetros por nombre si no se definen como solo posicionales.
  • Si la función se declara como def f(a, b, /, c):, entonces a y b solo se pueden pasar por posición.

Ejemplo:

def f(a, b, c=10): print(a, b, c) f(1, 2) # OK, c=10 por defecto f(a=1, b=2, c=3) # OK # Pero: def f(a, b, /, c=10): ... f(1, 2) # OK f(a=1, b=2, c=3) # ¡Error! a y b solo posicionales

Ejemplos de errores reales debido al desconocimiento de las sutilezas del tema


Historia

Un desarrollador implementó una función que, por convención, debería aceptar parámetros exclusivamente por nombre: registro con múltiples parámetros, algunos de ellos opcionales. Pero olvidaron declarar * — y los usuarios accidentalmente pasaron parámetros en un orden diferente por posición, lo que provocó un registro incorrecto y errores difíciles de rastrear.


Historia

En un proyecto con REST API, debido a un acuerdo implícito sobre el orden de los argumentos (usaron *args y no limitaron los parámetros por nombre) dejaron de funcionar las solicitudes después de implementar una nueva versión del cliente — porque args se desplazaron. Se corrigió introduciendo * explícitos y especificando solo argumentos nombrados.


Historia

En un gran proyecto corporativo, la función se amplió con nuevos parámetros con valores predeterminados, pero debido a una llamada incorrecta con valores posicionales, el código antiguo comenzó a insertar valores en otros parámetros, lo que provocó un procesamiento incorrecto de los datos. Resultó que los parámetros debían hacerse solo nombrados.