Saltar al contenido
🐍 Curso de Python
/

Módulo 1 · Lección 33 de 59

Parámetros y argumentos

Cómo pasarle datos a una función, la diferencia entre parámetro y argumento, y cuándo conviene nombrarlos al llamar.

⏱ 12 min de lectura

La función imprimir_cabecera() de la lección anterior tiene un defecto: siempre imprime exactamente lo mismo. Sirve para una tienda y para nada más.

Una función se vuelve útil de verdad cuando recibe datos de fuera y trabaja con ellos. Eso es lo que hay dentro de los paréntesis, que hasta ahora estaban vacíos.

Un hueco para el dato#

Escribe un nombre dentro de los paréntesis de la definición y ese nombre pasa a estar disponible dentro de la función como si fuera una variable:

python
def saludar(nombre):
        print(f"Hola, {nombre}. Bienvenido a la tienda.")


saludar("Ana")
saludar("Luis")
Salida en pantalla
Hola, Ana. Bienvenido a la tienda.
Hola, Luis. Bienvenido a la tienda.

La misma función, dos resultados distintos. En la primera llamada nombre vale "Ana"; en la segunda vale "Luis". Ese hueco es lo que hace que una función sea reutilizable en lugar de un simple atajo.

Parámetro no es lo mismo que argumento#

Las dos palabras se confunden constantemente, incluso entre profesionales, pero la distinción es sencilla y vale la pena tenerla clara porque los mensajes de error usan los términos con precisión:

TérminoDónde apareceEn el ejemplo
ParámetroEn la definición, entre los paréntesis del defnombre
ArgumentoEn la llamada, el valor concreto que pasas"Ana", "Luis"

Dicho de otra forma: el parámetro es la etiqueta del hueco y el argumento es lo que metes en él. El parámetro es siempre el mismo; el argumento cambia en cada llamada.

Varios parámetros#

Se separan por comas, tanto al definir como al llamar:

python
def mostrar_linea_pedido(producto, cantidad, precio):
        total = cantidad * precio
    print(f"{producto:<12} {cantidad:>3} x {precio:>6.2f} = {total:>7.2f}")


mostrar_linea_pedido("Camiseta", 2, 19.99)
mostrar_linea_pedido("Zapatillas", 1, 49.50)
Salida en pantalla
Camiseta       2 x  19.99 =   39.98
Zapatillas     1 x  49.50 =   49.50

El orden posicional#

Por defecto, los argumentos se emparejan con los parámetros por su posición: el primero con el primero, el segundo con el segundo. Python no mira los tipos ni intenta adivinar nada.

Si te equivocas de orden, no te avisa de inmediato. Te deja seguir hasta que algo revienta:

python
mostrar_linea_pedido(2, "Camiseta", 19.99)
Salida en pantalla
Traceback (most recent call last):
  File "/Users/erwin/curso-python/pedido.py", line 6, in <module>
    mostrar_linea_pedido(2, "Camiseta", 19.99)
    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/erwin/curso-python/pedido.py", line 2, in mostrar_linea_pedido
    total = cantidad * precio
            ~~~~~~~~~^~~~~~~~
TypeError: can't multiply sequence by non-int of type 'float'

Mira bien ese traceback: tiene dos bloques File. El de abajo señala la línea que ha petado, dentro de la función. El de arriba señala la llamada que provocó el problema. Cuando trabajas con funciones, el traceback se convierte en el recorrido completo desde donde empezó todo hasta donde acabó mal, y esa es justamente su utilidad.

Pasar argumentos por nombre#

Puedes decir explícitamente a qué parámetro va cada valor, escribiendo parametro=valor en la llamada. Así el orden deja de importar:

python
def registrar_envio(ciudad, urgente, asegurado):
        print(f"Envío a {ciudad}. Urgente: {urgente}. Asegurado: {asegurado}.")


registrar_envio("Valencia", True, False)
registrar_envio(ciudad="Valencia", urgente=True, asegurado=False)
registrar_envio(asegurado=False, ciudad="Valencia", urgente=True)
Salida en pantalla
Envío a Valencia. Urgente: True. Asegurado: False.
Envío a Valencia. Urgente: True. Asegurado: False.
Envío a Valencia. Urgente: True. Asegurado: False.

Las tres llamadas hacen lo mismo, pero no se leen igual. La primera, registrar_envio("Valencia", True, False), obliga a quien la lee a ir a buscar la definición para saber qué significan ese True y ese False. La segunda se explica sola.

Mezclar posicionales y por nombre#

Se pueden combinar, con una regla estricta: los posicionales van siempre primero. En cuanto usas uno por nombre, todos los siguientes tienen que ir también por nombre.

python
registrar_envio("Valencia", asegurado=False, urgente=True)    # válido

Al revés, ni siquiera llega a ejecutarse:

python
registrar_envio(ciudad="Valencia", True, False)
Salida en pantalla
  File "/Users/erwin/curso-python/envios.py", line 5
    registrar_envio(ciudad="Valencia", True, False)
                                                  ^
SyntaxError: positional argument follows keyword argument

El motivo de la regla es fácil de ver: si el primer hueco ya lo has ocupado por nombre, ¿qué posición le tocaría al siguiente argumento suelto? Python prefiere no adivinar.

Cuando faltan o sobran argumentos#

Aquí Python sí es tajante y el mensaje te dice exactamente qué pasa. Partimos de esta función:

python
def calcular_total(precio, cantidad):
        print(precio * cantidad)

Qué le puedes pasar a una función#

Cualquier cosa que sea un valor: números, textos, booleanos, listas, tuplas, diccionarios, e incluso el resultado de otra función.

python
def contar_palabras(frase):
        print(len(frase.split()))


def resumir_notas(notas):
        print(f"{len(notas)} notas, media {sum(notas) / len(notas):.2f}")


contar_palabras("El pedido llega el martes por la mañana")
resumir_notas([7, 9, 5, 8])
Salida en pantalla
8
4 notas, media 7.25