¿Qué son los métodos mágicos en Python?
ene, 4 2026
Si alguna vez has mirado el código de alguien más en Python y te has preguntado por qué hay funciones con dos guiones bajos por ambos lados, como __init__ o __len__, no estás loco. Esos son los métodos mágicos. No tienen nada que ver con hechizos ni varitas, pero sí con cómo Python hace que las cosas funcionen detrás de escena.
¿Qué son realmente los métodos mágicos?
Los métodos mágicos, también llamados dunder methods (por "double underscore"), son funciones especiales que Python llama automáticamente cuando ocurre cierta acción. No los llamas tú directamente. Python los invoca por ti. Es como si tuvieras un botón oculto en tu objeto que se presiona solo cuando algo sucede: cuando creas un objeto, cuando lo sumas, cuando lo conviertes a texto, cuando lo usas en un bucle.
Por ejemplo, cuando haces len(mi_lista), Python no está contando los elementos directamente. Está llamando internamente al método __len__() de esa lista. Lo mismo pasa con str(objeto) → llama a __str__(), o con objeto1 + objeto2 → llama a __add__().
Esto permite que tus propias clases se comporten como tipos nativos de Python. Puedes hacer que un objeto de tu clase se sume, se compare, se imprima o se itere como si fuera un número, una cadena o una lista. Sin métodos mágicos, tu clase sería un objeto rígido, sin vida. Con ellos, puedes darle personalidad.
Los 5 métodos mágicos más usados
No necesitas aprender todos los métodos mágicos de Python (hay más de 80), pero estos cinco son los que verás una y otra vez:
- __init__(self, ...): Se ejecuta cuando creas una nueva instancia de la clase. Es el constructor. Aquí es donde defines los atributos iniciales. Por ejemplo:
def __init__(self, nombre): self.nombre = nombre. - __str__(self): Define cómo se muestra tu objeto cuando lo imprimes con
print(objeto). Sin esto, verás algo como<__main__.MiClase object at 0x7f8b2c3d4e50>. Con__str__, puedes hacer que muestre algo como"Persona: Ana, 28 años". - __len__(self): Hace que tu objeto responda a
len(). Útil si tu clase representa una colección. Por ejemplo, una claseCajaque contiene objetos puede devolver cuántos hay dentro. - __add__(self, otro): Permite usar el operador
+con tus objetos. Puedes sumar dos objetos de tipoVectory que devuelva un nuevo vector resultante. - __eq__(self, otro): Define qué significa que dos objetos sean "iguales". Por defecto, Python compara las direcciones de memoria. Con
__eq__, puedes decir que dos objetos de tipoLibroson iguales si tienen el mismo ISBN.
Estos cinco cubren más del 90% de los casos reales. El resto son para casos más avanzados, como manejar atributos dinámicos (__getattr__), hacer que tu objeto sea iterable (__iter__), o incluso que se comporte como una función (__call__).
Un ejemplo real: una clase de fracción
Imagina que quieres crear una clase Fraction para manejar fracciones como 1/2 o 3/4, sin usar decimales. Quieres que se sumen, se comparen y se impriman como fracciones.
Así se vería:
class Fraction:
def __init__(self, numerador, denominador):
if denominador == 0:
raise ValueError("El denominador no puede ser cero")
self.numerador = numerador
self.denominador = denominador
def __str__(self):
return f"{self.numerador}/{self.denominador}"
def __add__(self, otra):
nuevo_num = self.numerador * otra.denominador + otra.numerador * self.denominador
nuevo_den = self.denominador * otra.denominador
return Fraction(nuevo_num, nuevo_den)
def __eq__(self, otra):
return self.numerador * otra.denominador == otra.numerador * self.denominador
def __lt__(self, otra):
return self.numerador * otra.denominador < otra.numerador * self.denominador
Ahora puedes hacer esto:
f1 = Fraction(1, 2)
f2 = Fraction(1, 3)
suma = f1 + f2
print(suma) # Salida: 5/6
print(f1 == Fraction(2, 4)) # Salida: True
print(f1 < f2) # Salida: False
¿No es increíble? No hay funciones especiales, no hay métodos raros. Solo usas los operadores normales, y Python los redirige a los métodos mágicos que tú definiste.
¿Por qué importan los métodos mágicos?
Porque Python está diseñado para ser expressive - expresivo. Quiere que escribas código que se lea como lenguaje natural. Si puedes escribir if usuario == administrador: en lugar de if usuario.es_administrador():, el código es más claro.
Librerías como pandas, numpy, o requests usan métodos mágicos por todas partes. Cuando haces df["columna"] en pandas, estás llamando a __getitem__. Cuando haces response.json(), el objeto response tiene un __getattr__ o un __call__ que lo hace posible.
Si quieres escribir código de Python que se sienta elegante, limpio y natural, los métodos mágicos no son un extra. Son la clave.
Errores comunes al usarlos
La mayoría de la gente que empieza con métodos mágicos comete estos errores:
- No devolver el valor correcto:
__add__debe devolver un nuevo objeto, no modificar el actual. Si lo modificas, rompes la inmutabilidad esperada. - Olvidar
__eq__cuando usas__hash__: Si quieres usar tu objeto como clave en un diccionario, necesitas ambos. Si no, Python lo rechazará. - Usarlos para lógica compleja: No pongas operaciones pesadas en
__str__o__len__. Estos métodos se llaman mucho, incluso en depuración. Si tardan 2 segundos en ejecutarse, tu IDE se volverá lento. - Confundir
__repr__con__str__:__repr__es para desarrolladores (debe ser lo más detallado posible).__str__es para usuarios finales (debe ser legible). Si no defines__repr__, Python usa__str__como respaldo, lo cual no es ideal.
Regla simple: __repr__ debe ser algo que puedas copiar y pegar en el intérprete y que funcione. Por ejemplo: "Fraction(1, 2)".
¿Cuándo NO usar métodos mágicos?
No los uses si:
- Estás haciendo algo que ya existe en una biblioteca estándar (como
collections.namedtupleodataclasses). - Tu clase es simple y no necesitas que se comporte como un tipo nativo.
- Estás trabajando en un equipo donde no todos conocen estos conceptos. La simplicidad a veces gana.
Los métodos mágicos son poderosos, pero no son una solución para todo. Son como un martillo neumático: excelente para romper concreto, inútil para clavar un clavo fino.
¿Qué sigue después?
Una vez que entiendas los métodos mágicos básicos, puedes explorar:
__iter__y__next__: para hacer objetos iterables.__getitem__y__setitem__: para hacer objetos indexables como listas.__call__: para que un objeto se comporte como una función.__enter__y__exit__: para usar tu objeto en bloqueswith.
Lo más importante: no intentes aprenderlos todos de golpe. Empieza con __init__, __str__, y __add__. Usa uno cada vez que crees una clase nueva. En unas semanas, te darás cuenta de que ya los usas sin pensar.
¿Qué pasa si no los uso?
Podrás escribir código funcional sin ellos. Pero tu código será más rígido, menos intuitivo, y más difícil de integrar con otras partes de Python. No serás un mal programador. Solo estarás ignorando una de las características más elegantes del lenguaje.
Imagina escribir un libro sin signos de puntuación. Puedes hacerlo. Pero no es lo mismo que leer uno bien escrito. Los métodos mágicos son la puntuación del código Python.
¿Los métodos mágicos son exclusivos de Python?
No, pero Python los popularizó. Otros lenguajes como Ruby y JavaScript tienen mecanismos similares, pero en Python son más consistentes, más accesibles y más usados en la práctica diaria. En Java o C#, tendrías que escribir métodos explícitos como toString() o equals(), lo que hace el código más verboso. En Python, todo se reduce a operadores naturales.
¿Puedo crear mis propios métodos mágicos?
No. Los métodos mágicos están definidos por el protocolo de Python. Solo puedes implementar los que ya existen. No puedes crear __mi_metodo_magico__ y esperar que Python lo llame. Si lo haces, será solo un método normal. Python solo reconoce los nombres que están en su especificación.
¿Por qué se llaman "mágicos" si no son mágicos?
Porque actúan sin que tú los llames explícitamente. Es como si Python los "adivinara". No es magia real, pero sí es una forma elegante de abstracción. El nombre se quedó por tradición, y aunque algunos programadores prefieren "dunder methods", "métodos mágicos" sigue siendo el término más usado en la comunidad hispanohablante.
¿Son lentos?
No. Son tan rápidos como cualquier otro método en Python. La sobrecarga de llamada es mínima. Lo que sí puede ser lento es si haces operaciones pesadas dentro de ellos, como leer archivos o hacer consultas a bases de datos. Eso no es culpa del método mágico, sino de lo que haces dentro.
¿Qué pasa si no defino __str__?
Python usará __repr__ si lo has definido. Si no, te mostrará el nombre de la clase y la dirección de memoria. No es un error, pero hace que el código sea menos legible. Es una buena práctica definir al menos __str__ para objetos que se muestran al usuario.

José Pérez Pérez
enero 5, 2026 AT 08:41Los métodos mágicos son lo que hace que Python sea tan elegante. No necesitas métodos como getLength() o toString(), simplemente usas len() o print() y funciona. Es como si el lenguaje supiera lo que querías decir.
Yo lo aprendí cuando hice una clase de puntos 2D y de pronto pude hacer p1 + p2 y me devolvía otro punto. Fue un momento "aha".
Todo esto suena obvio ahora, pero al principio me parecía magia negra.