- ¿Qué es el dispatching por llave?
- Ejemplo: Saludos en varios idiomas
- Opción 2: Usar un diccionario de funciones
- ¿Por qué este método es mejor?
- ¿Qué pasa cuando la clave del diccionario no existe?
- ¿Y si la función necesita más parámetros?
Cuando programamos en Python, usamos if, elif y else para tomar decisiones. Funciona bien… hasta que hay muchas condiciones y el código se vuelve un enredo.
¿La solución?
¿Qué es el dispatching por llave?
En Python, las funciones se pueden tratar igual que otras variables. Esto quiere decir que podemos:
- Asignarlas a una variable
- Guardarlas en una lista o diccionario
- Pasarlas como argumento a otra función
- Devolver funciones desde otras funciones
Gracias a eso, podemos crear un diccionario donde la clave sea una opción (como un idioma, una operación, un comando, etc.) y el valor sea una función que vamos a ejecutar. Esto hace que el código sea más limpio, más fácil de mantener y más ordenado.
Ejemplo: Saludos en varios idiomas
👋 Tenemos que saludar usuarios en diferentes idiomas. Primero vamos a hacerlo con un if-elif-else.
Opción 1: Usar if-elif-else
def saludo_en_ingles(nombre):
return f"Hello, {nombre}!"
def saludo_en_frances(nombre):
return f"Bonjour, {nombre}!"
def saludo_en_espanol(nombre):
return f"Hola, {nombre}!"
def saludar(idioma, nombre):
if idioma == "ingles":
return saludo_en_ingles(nombre)
elif idioma == "frances":
return saludo_en_frances(nombre)
elif idioma == "espanol":
return saludo_en_espanol(nombre)
else:
return "Error: idioma no válido"
print(saludar("ingles", "Carlos")) # Hello, Carlos!
print(saludar("frances", "Lucía")) # Bonjour, Lucía!
print(saludar("espanol", "María")) # Hola, María!
print(saludar("aleman", "Pedro")) # Error: idioma no válido
Este código funciona bien. Pero si quieres agregar más idiomas, hay que seguir añadiendo líneas al if-elif-else, lo que se hace tedioso con el tiempo.
Opción 2: Usar un diccionario de funciones
Vamos a reescribir lo mismo usando un diccionario para que sea más limpio y flexible.
def saludo_en_ingles(nombre):
return f"Hello, {nombre}!"
def saludo_en_frances(nombre):
return f"Bonjour, {nombre}!"
def saludo_en_espanol(nombre):
return f"Hola, {nombre}!"
# Función por defecto si la clave no existe
def mensaje_error(*args, **kwargs):
return "Error: idioma no válido"
# Diccionario que asocia cada idioma con su función
saludos = {
"ingles": saludo_en_ingles,
"frances": saludo_en_frances,
"espanol": saludo_en_espanol
}
def saludar(idioma, nombre):
# Buscamos la función correspondiente al idioma.
# Si no existe, usamos mensaje_error
funcion_saludo = saludos.get(idioma, mensaje_error)
return funcion_saludo(nombre)
print(saludar("ingles", "Carlos")) # Hello, Carlos!
print(saludar("frances", "Lucía")) # Bonjour, Lucía!
print(saludar("espanol", "María")) # Hola, María!
print(saludar("aleman", "Pedro")) # Error: idioma no válido
Ahora, si queremos agregar otro idioma, solo tenemos que definir una función y sumarla al diccionario saludos. La función principal saludar no necesita cambiar. ✅
¿Por qué este método es mejor?
| Característica | if-elif-else |
Diccionario de funciones |
|---|---|---|
| Fácil de leer y mantener | No, se vuelve largo | Sí, código más limpio |
| Agregar nuevas opciones | Requiere modificar la lógica | Solo agregar una entrada al diccionario |
| Código más modular | No mucho | Sí, cada función separada |
| Más flexible y escalable | Poco | Sí |
¿Qué pasa cuando la clave del diccionario no existe?
Si tratamos de buscar un idioma que no está en el diccionario, el método get devuelve None por defecto, lo que causaría un error si tratamos de llamarlo como función. Para evitar eso, le damos un valor por defecto usando get(clave, valor_por_defecto).
En nuestro caso:
funcion_saludo = saludos.get(idioma, mensaje_error)
Esto asegura que siempre se retorne una función válida.
¿Y si la función necesita más parámetros?
El diccionario de funciones también sirve para funciones que reciben varios argumentos. Solo asegúrate de que todas las funciones tengan la misma firma de parámetros (o usa args, *kwargs para aceptar distintos tipos de argumentos si necesitas más flexibilidad).
Resumen
- Las funciones en Python son objetos de primer orden y se pueden guardar en diccionarios.
- Podemos usar diccionarios para reemplazar estructuras condicionales largas.
- El método
dict.get(clave, valor_por_defecto)nos permite manejar claves faltantes sin errores. - Este patrón facilita la extensión y el mantenimiento del código.
Para acceder completo a curso necesitas un plan básico
El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.