Parámetros y argumentos: posicionales, nominales y predeterminados
Introducción
Cuando trabajamos con funciones en Python, la forma en que pasamos información a estas es fundamental para crear código flexible y reutilizable. Los parámetros y argumentos son los mecanismos que nos permiten enviar datos a nuestras funciones y controlar cómo se comportarán. En este artículo, exploraremos los diferentes tipos de parámetros que podemos utilizar en Python, desde los más básicos hasta los más avanzados, permitiéndonos crear funciones cada vez más versátiles. Comprender estas opciones es esencial para cualquier programador que desee dominar el lenguaje.
Diferencia entre parámetros y argumentos
Antes de profundizar, es importante aclarar la diferencia entre estos dos términos:
- Parámetros: Son las variables declaradas en la definición de una función.
- Argumentos: Son los valores reales que pasamos a la función cuando la llamamos.
# En esta definición, 'nombre' es un parámetro
def saludar(nombre):
print(f"Hola, {nombre}!")
# En esta llamada, 'Ana' es un argumento
saludar("Ana")
Parámetros posicionales
Los parámetros posicionales son la forma más básica de pasar información a una función. El orden en que enviamos los argumentos determina a qué parámetro corresponderá cada valor.
def describir_persona(nombre, edad, ciudad):
print(f"{nombre} tiene {edad} años y vive en {ciudad}.")
# Los argumentos se asignan en orden: nombre=Carlos, edad=28, ciudad=Madrid
describir_persona("Carlos", 28, "Madrid")
El orden es crucial en los parámetros posicionales. Si cambiamos el orden de los argumentos, obtendremos resultados diferentes:
# Aquí el orden está incorrecto: nombre=28, edad=Madrid, ciudad=Carlos
describir_persona(28, "Madrid", "Carlos")
# Resultado: 28 tiene Madrid años y vive en Carlos.
Parámetros nominales (o con nombre)
Los parámetros nominales nos permiten especificar explícitamente qué argumento corresponde a cada parámetro, independientemente del orden en que los pasemos.
def calcular_precio(producto, cantidad, precio_unitario):
total = cantidad * precio_unitario
return f"El costo total de {producto} es {total} euros."
# Usando argumentos con nombre
resultado = calcular_precio(
cantidad=5,
producto="cuadernos",
precio_unitario=2.50
)
print(resultado) # El costo total de cuadernos es 12.5 euros.
Los argumentos nominales hacen que nuestro código sea más legible y menos propenso a errores, especialmente cuando la función tiene muchos parámetros.
Combinando parámetros posicionales y nominales
Es posible combinar ambos tipos de parámetros en una misma llamada a función:
# Posicionales primero, luego nominales
calcular_precio("lápices", cantidad=12, precio_unitario=0.75)
# Una vez que usamos un argumento nominal, todos los siguientes deben ser nominales
# Esto es correcto:
calcular_precio("lápices", cantidad=12, precio_unitario=0.75)
# Esto generará un error:
# calcular_precio("lápices", cantidad=12, 0.75) # SyntaxError
Parámetros predeterminados (o por defecto)
Los parámetros predeterminados nos permiten asignar un valor por defecto a un parámetro. Si el argumento correspondiente no se proporciona durante la llamada, se utilizará el valor predeterminado.
def saludar_persona(nombre, saludo="Hola"):
print(f"{saludo}, {nombre}!")
# Usando solo el argumento obligatorio
saludar_persona("Laura") # Hola, Laura!
# Proporcionando ambos argumentos
saludar_persona("Laura", "Buenos días") # Buenos días, Laura!
Los parámetros con valores predeterminados siempre deben ir después de los parámetros sin valores predeterminados:
# Correcto
def configurar_usuario(nombre, edad, rol="usuario", activo=True):
# Código de la función
# Incorrecto - generará un error
# def configurar_usuario(nombre, rol="usuario", edad, activo=True):
# # Código de la función
Precauciones con valores mutables como predeterminados
Es importante tener cuidado cuando usamos objetos mutables (como listas o diccionarios) como valores predeterminados:
# ¡Esto puede causar problemas!
def añadir_elemento(nuevo_elemento, lista=[]):
lista.append(nuevo_elemento)
return lista
# Primera llamada
print(añadir_elemento(1)) # [1]
# Segunda llamada - ¡la lista no está vacía!
print(añadir_elemento(2)) # [1, 2]
El problema es que el valor predeterminado se crea una sola vez cuando se define la función, no cada vez que se llama. Para evitar este problema:
# Forma correcta
def añadir_elemento(nuevo_elemento, lista=None):
if lista is None:
lista = []
lista.append(nuevo_elemento)
return lista
# Ahora cada llamada usará una lista nueva
print(añadir_elemento(1)) # [1]
print(añadir_elemento(2)) # [2]
Número variable de argumentos posicionales (*args)
Python permite definir funciones que acepten un número variable de argumentos posicionales usando el operador *
:
def sumar(*numeros):
resultado = 0
for numero in numeros:
resultado += numero
return resultado
# Podemos pasar cualquier cantidad de argumentos
print(sumar(1, 2)) # 3
print(sumar(1, 2, 3, 4, 5)) # 15
print(sumar()) # 0
En este caso, numeros
será una tupla que contiene todos los argumentos posicionales pasados a la función.
Número variable de argumentos nominales (**kwargs)
De manera similar, podemos aceptar un número variable de argumentos nominales usando el operador **
:
def mostrar_datos(**datos):
for clave, valor in datos.items():
print(f"{clave}: {valor}")
# Podemos pasar cualquier cantidad de argumentos con nombre
mostrar_datos(nombre="Elena", edad=32, profesion="Ingeniera")
# nombre: Elena
# edad: 32
# profesion: Ingeniera
Aquí, datos
será un diccionario que contiene todos los argumentos nominales pasados a la función.
Orden de los parámetros
Si combinamos todos los tipos de parámetros, debemos seguir este orden:
- Parámetros posicionales sin valores predeterminados
- Parámetros con valores predeterminados
- Parámetros de longitud variable (
*args
) - Parámetros nominales sin valores predeterminados (solo Python 3.8+)
- Parámetros de longitud variable para argumentos con nombre (
**kwargs
)
def funcion_completa(
pos1, pos2, # Posicionales obligatorios
def1="valor1", def2="valor2", # Con valores predeterminados
*args, # Variables posicionales
nom1, nom2, # Nominales obligatorios (Python 3.8+)
**kwargs # Variables nominales
):
# Cuerpo de la función
pass
Resumen
Los parámetros y argumentos en Python nos ofrecen múltiples formas de proporcionar información a nuestras funciones. Los parámetros posicionales son simples pero dependen del orden, mientras que los nominales ofrecen mayor claridad. Los valores predeterminados hacen que nuestras funciones sean más flexibles, y los operadores *args
y **kwargs
nos permiten manejar un número variable de argumentos. Dominar estos conceptos es esencial para crear funciones versátiles y fáciles de usar. En el próximo artículo, exploraremos cómo las funciones pueden devolver valores, otro aspecto fundamental para aprovechar al máximo la modularidad que ofrece Python.