Parámetros y argumentos
🧭 Navegación:
- Anterior: Crear funciones con def
- Siguiente: Retorno de valores
¡Bienvenido al departamento de configuración de máquinas de nuestro almacén! Hasta ahora has aprendido a crear funciones básicas, pero ahora vamos a convertirlas en máquinas súper flexibles que pueden adaptarse a diferentes situaciones. Los parámetros y argumentos son como los controles y configuraciones que hacen que una máquina sea versátil.
🔧 ¿Qué son los parámetros y argumentos?
Imagina que tienes una máquina etiquetadora en tu almacén. Esta máquina puede crear etiquetas, pero necesita que le digas:
- ¿Qué texto poner?
- ¿De qué color debe ser?
- ¿Qué tamaño usar?
Estos “ajustes” que le das a la máquina son los argumentos, y los “controles” que tiene la máquina para recibir esos ajustes son los parámetros.
# Los parámetros son los "controles" de la máquina
def crear_etiqueta(texto, color, tamaño):
"""Máquina etiquetadora del almacén"""
etiqueta = f"[{color.upper()}] {texto} (Tamaño: {tamaño})"
return etiqueta
# Los argumentos son los "valores" que pasamos a esos controles
etiqueta1 = crear_etiqueta("FRÁGIL", "rojo", "grande")
etiqueta2 = crear_etiqueta("Electrónicos", "azul", "mediano")
📋 Tipos de parámetros
1. Parámetros obligatorios (posicionales)
Son como los controles esenciales de la máquina que SIEMPRE necesitas configurar:
def calcular_precio_envio(peso, distancia, tipo_envio):
"""
Calcula el precio de envío de un producto.
TODOS los parámetros son obligatorios - la máquina no funciona sin ellos.
"""
precio_base = peso * 2.5 # $2.5 por kg
precio_distancia = distancia * 0.1 # $0.1 por km
multiplicador = {
"express": 2.0,
"normal": 1.0,
"economico": 0.7
}
precio_final = (precio_base + precio_distancia) * multiplicador[tipo_envio]
return precio_final
# TODOS los argumentos son obligatorios
precio = calcular_precio_envio(5.2, 150, "express")
print(f"Precio de envío: ${precio:.2f}")
# ❌ Esto dará error - faltan argumentos
# precio = calcular_precio_envio(5.2) # Error: faltan distancia y tipo_envio
2. Parámetros opcionales (con valores por defecto)
Son como los controles con configuración automática - si no los ajustas, usan un valor por defecto:
def procesar_pedido(codigo_producto, cantidad, descuento=0, urgente=False, notas=""):
"""
Procesa un pedido con configuraciones opcionales.
Parámetros obligatorios: codigo_producto, cantidad
Parámetros opcionales: descuento, urgente, notas
"""
precio_base = obtener_precio(codigo_producto) * cantidad
precio_con_descuento = precio_base * (1 - descuento/100)
costo_urgente = 50 if urgente else 0
precio_final = precio_con_descuento + costo_urgente
pedido = {
"codigo": codigo_producto,
"cantidad": cantidad,
"precio_final": precio_final,
"urgente": urgente,
"notas": notas if notas else "Sin notas especiales"
}
return pedido
# Usando solo parámetros obligatorios
pedido1 = procesar_pedido("LAP001", 2)
# Usando algunos parámetros opcionales
pedido2 = procesar_pedido("MOU001", 1, descuento=10)
# Usando todos los parámetros
pedido3 = procesar_pedido("TEC001", 1, descuento=15, urgente=True, notas="Cliente VIP")
3. Parámetros con palabras clave
Puedes especificar exactamente qué control quieres ajustar usando el nombre del parámetro:
def generar_reporte_inventario(categoria, incluir_agotados=True, ordenar_por="nombre", formato="texto"):
"""Genera un reporte personalizado del inventario"""
print(f"Generando reporte de {categoria}")
print(f"Incluir agotados: {incluir_agotados}")
print(f"Ordenar por: {ordenar_por}")
print(f"Formato: {formato}")
# Argumentos posicionales (en orden)
generar_reporte_inventario("Electrónicos", False, "precio", "PDF")
# Argumentos con palabras clave (cualquier orden)
generar_reporte_inventario(
categoria="Electrónicos",
formato="PDF",
ordenar_por="precio",
incluir_agotados=False
)
# Mezclando posicionales y por palabra clave
generar_reporte_inventario("Electrónicos", ordenar_por="stock", formato="Excel")
🌟 Parámetros avanzados: *args y **kwargs
*args: Para listas variables de argumentos
Como una máquina que puede procesar cualquier cantidad de elementos:
def calcular_total_productos(*precios):
"""
Calcula el total de productos sin importar cuántos sean.
*precios recoge TODOS los argumentos posicionales en una tupla.
"""
total = 0
print(f"Procesando {len(precios)} productos:")
for i, precio in enumerate(precios, 1):
print(f" Producto {i}: ${precio:.2f}")
total += precio
return total
# Puedes pasar cualquier cantidad de precios
total1 = calcular_total_productos(25.99)
total2 = calcular_total_productos(25.99, 89.50, 12.75)
total3 = calcular_total_productos(100, 200, 300, 400, 500)
print(f"Totales: ${total1:.2f}, ${total2:.2f}, ${total3:.2f}")
**kwargs: Para parámetros con nombre variables
Como una máquina súper configurable que acepta cualquier configuración que le envíes:
def crear_producto_personalizado(nombre, precio, **caracteristicas):
"""
Crea un producto con características personalizables.
**caracteristicas recoge TODOS los argumentos con nombre en un diccionario.
"""
producto = {
"nombre": nombre,
"precio": precio
}
# Agregar todas las características adicionales
producto.update(caracteristicas)
print(f"📦 Producto: {nombre}")
print(f"💰 Precio: ${precio:.2f}")
print("🔧 Características adicionales:")
for caracteristica, valor in caracteristicas.items():
print(f" {caracteristica}: {valor}")
return producto
# Cada producto puede tener características diferentes
laptop = crear_producto_personalizado(
"Laptop Gaming",
1500.00,
procesador="Intel i7",
ram="16GB",
almacenamiento="1TB SSD",
tarjeta_grafica="RTX 4060",
garantia="2 años"
)
mouse = crear_producto_personalizado(
"Mouse Inalámbrico",
35.99,
conectividad="Bluetooth",
bateria="6 meses",
color="Negro"
)
Combinando *args y **kwargs
La máquina más flexible del almacén que acepta cualquier configuración:
def procesar_venta_flexible(vendedor, *productos, **opciones_venta):
"""
Procesa una venta súper flexible.
vendedor: Parámetro obligatorio
*productos: Cualquier cantidad de productos
**opciones_venta: Cualquier opción adicional
"""
print(f"👨💼 Vendedor: {vendedor}")
print(f"📦 Productos ({len(productos)}):")
total = 0
for i, producto in enumerate(productos, 1):
print(f" {i}. {producto['nombre']} - ${producto['precio']:.2f}")
total += producto['precio']
print(f"💰 Subtotal: ${total:.2f}")
# Procesar opciones adicionales
if opciones_venta:
print("⚙️ Opciones especiales:")
for opcion, valor in opciones_venta.items():
print(f" {opcion}: {valor}")
# Aplicar descuentos si existen
if 'descuento' in opciones_venta:
descuento = total * (opciones_venta['descuento'] / 100)
total -= descuento
print(f"🎉 Descuento aplicado: -${descuento:.2f}")
print(f"💳 Total final: ${total:.2f}")
return total
# Ejemplo de uso súper flexible
venta = procesar_venta_flexible(
"Ana García", # vendedor (obligatorio)
{"nombre": "Laptop", "precio": 1500}, # *productos
{"nombre": "Mouse", "precio": 35},
{"nombre": "Teclado", "precio": 120},
descuento=10, # **opciones_venta
metodo_pago="tarjeta",
cliente_vip=True,
envio_express=True
)
🎯 Orden de los parámetros
En Python hay un orden específico que debes seguir al definir parámetros:
def funcion_completa(
obligatorio1, # 1. Parámetros posicionales obligatorios
obligatorio2,
opcional1="valor1", # 2. Parámetros opcionales (con default)
opcional2="valor2",
*args, # 3. *args (argumentos posicionales variables)
clave_solo1, # 4. Keyword-only arguments
clave_solo2="default",
**kwargs # 5. **kwargs (argumentos con clave variables)
):
"""Función que muestra el orden correcto de parámetros"""
print(f"Obligatorios: {obligatorio1}, {obligatorio2}")
print(f"Opcionales: {opcional1}, {opcional2}")
print(f"Args adicionales: {args}")
print(f"Clave solo: {clave_solo1}, {clave_solo2}")
print(f"Kwargs: {kwargs}")
# Ejemplo de uso
funcion_completa(
"req1", "req2", # obligatorios
"opt1", # opcional1
"extra1", "extra2", # *args
clave_solo1="valor", # keyword-only
parametro_extra="valor" # **kwargs
)
🏭 Ejemplos prácticos del almacén
1. Sistema de descuentos flexible
def aplicar_descuentos(precio_base, *descuentos_porcentaje, cantidad=1, cliente_vip=False, **promociones):
"""
Sistema flexible de descuentos del almacén.
Args:
precio_base: Precio original del producto
*descuentos_porcentaje: Múltiples descuentos que se aplican secuencialmente
cantidad: Cantidad de productos (con descuento por volumen)
cliente_vip: Si es cliente VIP (descuento especial)
**promociones: Promociones adicionales
"""
precio_actual = precio_base
print(f"💰 Precio base: ${precio_base:.2f}")
# Aplicar descuentos secuenciales
for i, descuento in enumerate(descuentos_porcentaje, 1):
descuento_valor = precio_actual * (descuento / 100)
precio_actual -= descuento_valor
print(f"🎯 Descuento {i} ({descuento}%): -${descuento_valor:.2f} = ${precio_actual:.2f}")
# Descuento por cantidad
precio_total = precio_actual * cantidad
if cantidad >= 5:
descuento_volumen = precio_total * 0.05 # 5% por volumen
precio_total -= descuento_volumen
print(f"📦 Descuento por volumen (5%): -${descuento_volumen:.2f}")
# Descuento VIP
if cliente_vip:
descuento_vip = precio_total * 0.10 # 10% VIP
precio_total -= descuento_vip
print(f"⭐ Descuento VIP (10%): -${descuento_vip:.2f}")
# Promociones especiales
for promo, valor in promociones.items():
if promo == "codigo_promocional" and valor == "VERANO2024":
descuento_promo = precio_total * 0.15
precio_total -= descuento_promo
print(f"🌞 Código promocional: -${descuento_promo:.2f}")
elif promo == "descuento_adicional":
precio_total -= valor
print(f"💸 Descuento adicional: -${valor:.2f}")
print(f"💳 PRECIO FINAL: ${precio_total:.2f}")
return precio_total
# Ejemplo: múltiples descuentos en una venta compleja
precio_final = aplicar_descuentos(
200.00, # precio_base
10, 5, # descuentos del 10% y 5%
cantidad=6, # 6 productos (activa descuento por volumen)
cliente_vip=True, # cliente VIP
codigo_promocional="VERANO2024", # promoción especial
descuento_adicional=20.00 # descuento extra
)
2. Generador de reportes configurables
def generar_reporte(titulo, *datos, formato="texto", incluir_fecha=True,
separador="-", **metadatos):
"""
Generador flexible de reportes del almacén.
"""
from datetime import datetime
# Encabezado del reporte
linea_separador = separador * 50
print(linea_separador)
print(f"📊 {titulo.upper()}")
if incluir_fecha:
fecha_actual = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"📅 Generado: {fecha_actual}")
# Metadatos adicionales
if metadatos:
print("ℹ️ Información adicional:")
for clave, valor in metadatos.items():
print(f" {clave.replace('_', ' ').title()}: {valor}")
print(linea_separador)
# Datos del reporte
if formato == "texto":
for i, dato in enumerate(datos, 1):
print(f"{i}. {dato}")
elif formato == "lista":
for dato in datos:
print(f"• {dato}")
elif formato == "numerado":
for i, dato in enumerate(datos, 1):
print(f"[{i:03d}] {dato}")
print(linea_separador)
print(f"📈 Total de elementos: {len(datos)}")
return len(datos)
# Ejemplos de uso
reporte1 = generar_reporte(
"Productos más vendidos",
"Laptop Gaming - 45 unidades",
"Mouse Inalámbrico - 32 unidades",
"Teclado Mecánico - 28 unidades",
formato="numerado",
generado_por="Sistema automático",
categoria="Electrónicos",
periodo="Último mes"
)
reporte2 = generar_reporte(
"Inventario crítico",
"Monitor 4K - Stock: 2",
"Webcam HD - Stock: 1",
"Parlantes - Stock: 3",
formato="lista",
separador="=",
incluir_fecha=True,
urgencia="Alta",
accion_requerida="Reposición inmediata"
)
🔍 Introspección de funciones
Python te permite inspeccionar las máquinas que has creado:
def maquina_compleja(param1, param2="default", *args, param_clave, **kwargs):
"""Una máquina compleja para demostrar introspección"""
pass
# Inspeccionar los parámetros de la función
import inspect
print("🔍 Análisis de la máquina:")
signature = inspect.signature(maquina_compleja)
for name, param in signature.parameters.items():
print(f"⚙️ {name}:")
print(f" Tipo: {param.kind}")
print(f" Default: {param.default if param.default != param.empty else 'Sin default'}")
# Información adicional
print(f"\n📋 Documentación: {maquina_compleja.__doc__}")
print(f"🏷️ Nombre: {maquina_compleja.__name__}")
🎯 Comprueba tu comprensión
Ejercicio 1: Calculadora de envíos
Crea una función que calcule el costo de envío con múltiples opciones:
def calcular_envio(peso, distancia, tipo="normal", urgente=False, seguro=False, **extras):
"""
Calcula el costo de envío con múltiples opciones.
Args:
peso: Peso en kg (obligatorio)
distancia: Distancia en km (obligatorio)
tipo: "normal", "express", "economico" (default: "normal")
urgente: Si requiere entrega urgente (default: False)
seguro: Si incluye seguro (default: False)
**extras: Servicios adicionales
"""
# Tu código aquí
pass
# Pruebas
costo1 = calcular_envio(2.5, 100)
costo2 = calcular_envio(5.0, 200, tipo="express", urgente=True)
costo3 = calcular_envio(1.2, 50, seguro=True, embalaje_especial=25, manejo_fragil=15)
Ejercicio 2: Procesador de productos
Crea una función que procese una lista variable de productos:
def procesar_productos(*productos, descuento_global=0, **configuraciones):
"""
Procesa múltiples productos con configuraciones flexibles.
Args:
*productos: Lista variable de diccionarios de productos
descuento_global: Descuento aplicado a todos los productos
**configuraciones: Configuraciones adicionales del procesamiento
"""
# Tu código aquí
pass
# Prueba
productos = [
{"nombre": "Laptop", "precio": 1000, "categoria": "Electronica"},
{"nombre": "Mouse", "precio": 30, "categoria": "Accesorios"}
]
resultado = procesar_productos(
*productos,
descuento_global=10,
aplicar_impuesto=True,
moneda="USD",
incluir_garantia=True
)
Ejercicio 3: Validador flexible
Crea una función que valide datos con reglas variables:
def validar_datos(datos, *reglas_obligatorias, permitir_extras=False, **reglas_opcionales):
"""
Valida un diccionario de datos contra reglas flexibles.
Args:
datos: Diccionario con datos a validar
*reglas_obligatorias: Campos que deben existir
permitir_extras: Si permite campos no especificados
**reglas_opcionales: Validaciones opcionales por campo
"""
# Tu código aquí
pass
# Prueba
datos_usuario = {
"nombre": "Ana García",
"email": "ana@email.com",
"edad": 25,
"telefono": "555-0123"
}
es_valido = validar_datos(
datos_usuario,
"nombre", "email", # campos obligatorios
permitir_extras=True,
edad_minima=18,
email_formato=r".*@.*\..*"
)
💡 Mejores prácticas
- Orden consistente: Siempre sigue el orden estándar de parámetros
- Nombres descriptivos: Los parámetros deben explicar qué representan
- Valores por defecto sensatos: Usa defaults que tengan sentido en el contexto
- Documentación clara: Explica todos los parámetros en el docstring
- **No abuses de *args y kwargs: Úsalos cuando realmente aporten flexibilidad
- Validación de entrada: Verifica que los argumentos tengan sentido
🎉 ¡Felicitaciones!
Has aprendido a crear máquinas súper configurables para tu almacén digital. Ahora puedes:
- ✅ Crear funciones flexibles con parámetros opcionales
- ✅ Usar argumentos por palabra clave para mayor claridad
- ✅ Implementar funciones que acepten cantidad variable de argumentos
- ✅ Combinar diferentes tipos de parámetros eficientemente
- ✅ Hacer tu código más reutilizable y mantenible
En la siguiente sección aprenderemos sobre valores de retorno: cómo hacer que nuestras máquinas nos entreguen exactamente lo que necesitamos.
🧭 Navegación:
- Anterior: Crear funciones con def
- Siguiente: Retorno de valores