Regístrate para acceder a más de 15 cursos gratuitos de programación con un simulador

Dispatch por clave (datos) Python: Polimorfismo

A veces, nuestro código necesita actuar diferente según el tipo de dato o el entorno. ¿Cómo tomamos esas decisiones de forma limpia y flexible? Aquí entra el dispatch dinámico.

En esta lección vas a:

  • Descubrir qué es el dispatch y cómo funciona.
  • Diferenciar entre dispatch estático y dinámico.
  • Implementar dispatch dinámico en Python con condicionales, diccionarios y archivos externos.
  • Ver cómo todo esto se relaciona con el polimorfismo.

¿Qué es el dispatch?

Es una manera de seleccionar qué función, método o conjunto de datos usar, dependiendo de algún valor (por ejemplo, una palabra como "producción" o "desarrollo") o el tipo de variable que tengamos.

👉 En términos sencillos, le decimos al programa: Dependiendo de esto que tenemos aquí, usa tal cosa en vez de esa otra.

Tipos de dispatch

Tipo ¿Cuándo ocurre? ¿Qué lo caracteriza?
dispatch estático Durante la compilación Ya está decidido qué función se ejecutará
dispatch dinámico Durante la ejecución del programa La función se decide en tiempo real

🐍 Python no compila como otros lenguajes, así que lo que más usamos es el dispatch dinámico.


Dispatch dinámico con condicionales

Supongamos que estamos construyendo una aplicación y queremos cargar diferentes configuraciones dependiendo del ambiente (es decir, si estamos en desarrollo o ya en producción).

def get_config(env):
    if env == 'development':
        return {
            'debug': True,
            'database': 'sqlite:///:memory:',
        }
    elif env == 'production':
        return {
            'debug': False,
            'database': 'postgresql://user:pass@localhost/db',
        }
    else:
        return {
            'debug': True,
            'database': 'sqlite:///:memory:',
        }

# Probar los diferentes entornos
print(get_config('development'))  # {'debug': True, 'database': 'sqlite:///:memory:'}
print(get_config('production'))   # {'debug': False, 'database': 'postgresql://user:pass@localhost/db'}

Este es un ejemplo típico de dispatch dinámico. La función get_config(env) nos devuelve una configuración distinta dependiendo del valor de env.

Pero… ¿qué pasa si tenemos más ambientes como "testing", "staging", o "qa"? El código se empieza a llenar de if y elif, y se vuelve difícil de leer.

Mejorar nuestro código con dispatch por diccionario

Una forma mucho más limpia y elegante de hacer esto en Python es usando diccionarios para mapear claves a valores.

def get_config(env):
    configurations = {
        'development': {
            'debug': True,
            'database': 'sqlite:///:memory:',
        },
        'production': {
            'debug': False,
            'database': 'postgresql://user:pass@localhost/db',
        },
    }

    # Si la clave no existe, usa 'development' como predeterminado
    return configurations.get(env, configurations['development'])

print(get_config('production'))   
# {'debug': False, 'database': 'postgresql://user:pass@localhost/db'}
print(get_config('qa'))           
# Usa configuración de desarrollo como predeterminada

Este código hace exactamente lo mismo, pero es más claro y fácil de mantener. Si en el futuro queremos agregar un nuevo ambiente, solo añadimos una nueva entrada al diccionario.


Usar archivos de configuración externos (como JSON)

A veces necesitamos que el código sea aún más flexible. Por ejemplo, si queremos que otras personas (que no escriben código) puedan cambiar configuraciones sin tocar el programa.

Una opción es guardar las configuraciones en un archivo JSON.

Ejemplo: archivo config.json

Este puede ser el contenido del archivo:

{
  "development": {
    "debug": true,
    "database": "sqlite:///:memory:"
  },
  "production": {
    "debug": false,
    "database": "postgresql://user:pass@localhost/db"
  }
}

Código en Python que lee este archivo

import json

# Abrimos y cargamos el archivo JSON
with open('config.json', 'r') as file:
    config = json.load(file)

def get_config(env):
    return config.get(env, config['development'])

print(get_config('production'))
print(get_config('testing'))  # Devuelve configuración por defecto (development)

Este enfoque tiene muchas ventajas:

  • Podemos cambiar configuraciones sin tocar el código.
  • Es más profesional.
  • Útil cuando trabajamos con sistemas grandes que se ejecutan en diferentes entornos.

¿Qué tiene que ver esto con el polimorfismo?

Cuando usamos dispatch dinámico, lo que estamos haciendo muchas veces está muy relacionado con polimorfismo —un concepto de la programación orientada a objetos.

El polimorfismo nos permite usar el mismo nombre de función o método para hacer cosas diferentes, dependiendo del tipo de dato con el que estemos trabajando.

En nuestro caso, get_config(env) se comporta diferente dependiendo del valor de env. Eso es un comportamiento polimórfico.

Por ejemplo, también podríamos tener varias funciones diferentes y llamarlas dinámicamente desde un solo punto de entrada. Aquí un ejemplo con funciones:

def saludo_es():
    return "Hola"

def saludo_en():
    return "Hello"

def saludo_fr():
    return "Bonjour"

# Diccionario de dispatch de funciones
saludos = {
    'es': saludo_es,
    'en': saludo_en,
    'fr': saludo_fr,
}

def saludar(idioma):
    # Retorna la función correspondiente. Si no existe, usa español.
    return saludos.get(idioma, saludo_es)()

print(saludar('en'))  # Hello
print(saludar('fr'))  # Bonjour
print(saludar('de'))  # Hola (por defecto)

Este tipo de técnica es muy poderosa cuando queremos que un mismo punto de entrada se encargue de ejecutar diferentes comportamientos.



Resumen

  • El dispatch nos permite elegir funciones, métodos o datos en tiempo de ejecución según un valor o tipo.
  • Usamos principalmente dispatch dinámico en Python.
  • Se puede implementar usando if, elif, pero es más limpio usar diccionarios.
  • Si usamos muchas configuraciones, podemos moverlas a un archivo externo como JSON.
  • El dispatch dinámico está estrechamente relacionado con el polimorfismo, porque permite que el programa actúe diferente con la misma estructura.
  • Esta técnica mejora la modularidad, la organización del código y facilita el mantenimiento.

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.

Obtener acceso
130
cursos
1000
ejercicios
2000+
horas de teoría
3200
test

Obtén acceso

Cursos de programación para principiantes y desarrolladores experimentados. Comienza tu aprendizaje de forma gratuita

  • 130 cursos, 2000+ horas de teoría
  • 1000 ejercicios prácticos en el navegador
  • 360 000 estudiantes
Al enviar el formulario, aceptas el «Política de privacidad» y los términos de la «Oferta», y también aceptas los «Términos y condiciones de uso»

Nuestros graduados trabajan en empresas como:

Bookmate
Health Samurai
Dualboot
ABBYY