Argumentos posicionales vs keyword en Python

Cuando defines una función con def greet(name, age): estás declarando parámetros — los nombres que viven dentro de la función. Cuando la llamas con greet("Ana", 30) estás pasando argumentos — los valores concretos que llenan esos parámetros. Esa distinción importa porque Python ofrece dos maneras de hacer el emparejamiento, y elegir mal puede enviarte valores al parámetro equivocado sin ningún aviso.

La primera manera es posicional: el orden lo es todo. El primer argumento va al primer parámetro, el segundo al segundo, y así. Es como llenar un formulario en papel — los campos están fijos y tú los rellenas de arriba a abajo. Si te equivocas de orden, los datos quedan cruzados y Python no se queja porque no puede saber que 30 era para el nombre y "Ana" para la edad.

La segunda manera son los keyword arguments (argumentos nombrados): en lugar de confiar en la posición, dices explícitamente a qué parámetro va cada valor con la sintaxis nombre=valor. Eso desacopla completamente el orden de la llamada de la firma de la función. Puedes poner los argumentos en cualquier orden siempre que los nombres coincidan exactamente con los parámetros.

Python tiene una sola regla de mezcla que no tiene excepciones: los keyword arguments siempre van después de todos los posicionales en una misma llamada. Si intentas ponerlos antes, obtienes un SyntaxError inmediato. El motivo es de diseño: una vez que nombras un argumento, el intérprete ya no puede usar la posición para resolver el siguiente, así que tiene sentido que los nombrados cierren la lista.

¿Cuándo vale la pena usar keyword arguments? Sobre todo cuando una función tiene tres o más parámetros, cuando varios parámetros son del mismo tipo (varios booleanos, varios strings), o cuando llamas a una función que no escribiste tú y no quieres tener que memorizar el orden exacto. Una llamada como connect(host="localhost", port=5432, timeout=10) es autoexplicativa; connect("localhost", 5432, 10) te obliga a abrir la documentación para estar seguro.

# Función de ejemplo: enviar una notificación
def send_notification(recipient, subject, body, priority="normal", html=False):
    label = f"[{priority.upper()}]"
    format_tag = "HTML" if html else "texto plano"
    print(f"{label} Para: {recipient}")
    print(f"  Asunto : {subject}")
    print(f"  Formato: {format_tag}")
    print(f"  Cuerpo : {body[:40]}...")


# ── Llamada 100% posicional ──────────────────────────────────────────────────
# El orden debe coincidir EXACTAMENTE con la definición.
send_notification("ana@example.com", "Bienvenida", "Hola Ana, tu cuenta está lista.")

print("---")

# ── Llamada 100% keyword ─────────────────────────────────────────────────────
# El orden ya no importa; cada valor va al parámetro correcto por nombre.
send_notification(
    subject="Alerta de seguridad",
    recipient="ops@example.com",
    priority="high",
    body="Se detectó un acceso inusual a tu cuenta.",
)

print("---")

# ── Llamada mixta: posicionales primero, keywords al final ───────────────────
# recipient y subject se resuelven por posición; el resto, por nombre.
send_notification(
    "dev@example.com",
    "Deploy completado",
    body="La versión 2.4.1 está en producción.",
    html=True,          # parámetro booleano: nombrarlo evita confusión de orden
)

Qué está pasando en cada llamada

En la primera llamada, los cinco valores van por posición estricta. Funciona, pero si alguien invirtiera subject y body por descuido el programa seguiría corriendo — solo con los campos cambiados de lugar, un bug silencioso clásico.

La segunda llamada es completamente nombrada y hasta invierte el orden de subject y recipient. Python los empareja por nombre, no por posición, así que el resultado es idéntico a si los hubiera puesto en el orden “correcto”. Fíjate además que html y priority tienen valores por defecto en la firma — eso los hace opcionales, pero cuando sí los pasas, usar el nombre elimina cualquier ambigüedad sobre cuál es cuál.

La tercera llamada mezcla ambos estilos: los dos primeros argumentos son posicionales (van exactamente en el orden de la definición), y a partir de body todo es nombrado. Es un patrón muy común cuando los primeros parámetros son “obvios” por contexto (el destinatario, el asunto) y los opcionales necesitan ser explícitos.

El parámetro html=True merece atención especial. Sin el nombre, tendrías send_notification("dev@...", "Deploy...", "La versión...", True) — ese True flotando al final no le dice nada a quien lee el código. Con el nombre, la intención es inmediata.

Errores que debes conocer

Error: poner un keyword argument antes de un posicional rompe la sintaxis porque el intérprete ya no puede resolver las posiciones restantes.

# ❌ Wrong
send_notification(recipient="ana@example.com", "Bienvenida", "Hola Ana.")

# ✅ Right
send_notification("ana@example.com", "Bienvenida", "Hola Ana.")
# o bien, nombrar todos si cambias el orden
send_notification(recipient="ana@example.com", subject="Bienvenida", body="Hola Ana.")

Una vez que usas nombre=valor, todos los argumentos que siguen deben ser nombrados también.


Error: pasar el mismo argumento dos veces — una por posición y otra por nombre — causa TypeError porque Python no sabe cuál de los dos valores usar.

# ❌ Wrong
send_notification("ana@example.com", recipient="ana@example.com", subject="Hola", body="...")
# TypeError: send_notification() got multiple values for argument 'recipient'

# ✅ Right
send_notification("ana@example.com", subject="Hola", body="...")

El primero ya cubrió recipient por posición; nombrarlo de nuevo es una contradicción que Python rechaza en tiempo de ejecución.


Error: asumir que el orden de los keyword arguments afecta la ejecución cuando en realidad Python siempre los empareja por nombre.

# ❌ Wrong — suposición incorrecta de que el orden importa aquí
send_notification(body="Texto", subject="Asunto", recipient="x@x.com")
# ✅ Right — funciona igual que en el orden "canónico"
send_notification(recipient="x@x.com", subject="Asunto", body="Texto")

Con keyword arguments el orden es irrelevante; cambiar la secuencia no cambia qué valor recibe cada parámetro.

54

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio