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

Dispatch dinámico Python: Polimorfismo

Hablaremos sobre cómo Python elige qué método ejecutar cuando usamos objetos distintos que tienen métodos con el mismo nombre. Vamos a hacerlo paso a paso, como si estuviéramos hablando con un amigo sobre cómo funciona todo esto “internamente en Python”.


La dinámica de la dinamita: ¡Desencadenando métodos!

Python usa algo que se llama dispatch dinámico de métodos.

Suena técnico, pero la idea es muy sencilla: en vez de decidir qué método ejecutar en el momento en que escribimos el código, Python toma esa decisión cuando el programa ya está corriendo, basándose en el tipo del objeto.

Veamos un ejemplo sencillo:

def print_name(obj):
    print(obj.get_name())

print_name(User({'name': 'Mike'}))

Aquí print_name() es una función que utiliza get_name(), pero no sabe qué tipo de objeto va a recibir. Solo espera que el objeto tenga ese método.

Entonces, ¿qué pasa cuando se llama print_name(User(...))? Vamos a ver cómo está definido ese objeto User.


Ejemplo completo

class User:
    def __init__(self, data):
        self.name = data['name']

    def get_name(self):
        return self.name

def print_name(obj):
    print(obj.get_name())

print_name(User({'name': 'Mike'}))

Aquí es donde entra el polimorfismo:

  • Tenemos una clase User que tiene un método get_name().
  • La función print_name() no se preocupa por el tipo de objeto que le llega, solo necesita que tenga un método get_name().

Python, cuando ejecuta obj.get_name(), busca internamente cuál es la clase de ese objeto, luego revisa qué métodos tiene esa clase y finalmente usa el que coincida con ese nombre.

Eso es exactamente el trabajo que hace el mecánico del lenguaje — el dispatch dinámico.


¿Y cómo hace Python todo eso?

Vamos a meternos un poquito más en las “tripas” del lenguaje. Lo que Python hace por debajo se puede parecer a este código:

class User:
    def __init__(self, name):
        self.name = name

    def get_name(self):
        return self.name

def call_method(self, method_name, *args):
    # Acceder al diccionario de la clase
    methods = getattr(self, '__class__').__dict__

    # Buscar el método por nombre
    method = methods.get(method_name)

    if method:
        return method(self, *args)  # Llamamos manualmente, pasando self
    raise Exception('Método no encontrado')

call_method(User('Mike'), 'get_name')

Este código hace manualmente lo mismo que hace Python automáticamente. Veamos qué está pasando:

  1. Usamos getattr(self, __class__) para obtener la clase del objeto.
  2. Accedemos al __dict__ de la clase, que es un diccionario donde están definidos sus métodos y atributos.
  3. Buscamos el método por nombre (method_name).
  4. Si lo encontramos, lo llamamos explícitamente, pasando el objeto como self.

Esto nos muestra claramente una idea importante: en Python, los métodos de clase por dentro son simplemente funciones que reciben como primer argumento al objeto (self).


Dispatch simple vs múltiple

Este tipo de gestión de métodos basada únicamente en la clase del objeto se conoce como dispatch simple. En otros lenguajes como Clojure, que no usan clases al estilo tradicional, a veces usan lo que se llama dispatch múltiple, donde una función elige qué versión ejecutar con base en varios parámetros, no solo el tipo de uno de ellos.

En Python, podemos simular estas ideas, pero el modelo que usa por defecto es el de dispatch simple: elige el método con base en la clase del objeto que recibe el mensaje o llamado.


¿Por qué tengo que saber todo esto?

Entender cómo funciona esto a nivel interno nos da herramientas para:

  • Escribir mejor código orientado a objetos.
  • Diseñar funciones y clases más flexibles.
  • Aprovechar al máximo el polimorfismo, sin necesidad de repetir código para cada tipo.
  • Comprender errores que en otro momento serían difíciles de detectar.



Resumen

  • Polimorfismo permite que distintos objetos respondan a la misma operación de manera diferente.
  • Python usa dispatch dinámico: decide qué método llamar en tiempo de ejecución, basándose en la clase del objeto.
  • Los métodos son funciones especiales que reciben el objeto como primer parámetro (self).
  • Internamente, Python busca el método en el diccionario de la clase (__dict__).
  • El modelo que usa Python se basa en dispatch simple, aunque otros lenguajes permiten más complejidad con dispatch múltiple.

Materiales adicionales

  1. Multimethods“

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