En Python, los métodos Dunder (abreviatura de “double underscore”) son aquellos cuyo nombre comienza y termina con dos guiones bajos (__).
Estos métodos no se llaman directamente, sino que son invocados automáticamente por el intérprete de Python en diversas situaciones (como operaciones aritméticas, manipulación de secuencias y gestión del contexto).
También conocidos como métodos mágicos o especiales
Algunos de los métodos dunder más comunes son:
| Método | Descripción |
|---|---|
__init__ | Inicializa una nueva instancia de una clase |
__str__ | Devuelve una string de un objeto, amigable para el usuario |
__repr__ | Devuelve una string de un objeto, amigable para el desarrollador |
__len__ | Devuelve la longitud de un objeto |
__getitem__ | Permite acceder a elementos mediante índices |
__setitem__ | Permite asignar valores a elementos mediante índices |
__delitem__ | Permite eliminar elementos mediante índices |
__iter__ | Devuelve un iterador para el objeto |
__next__ | Devuelve el siguiente elemento del iterador |
Implementación de Métodos Dunder
Veamos cómo se implementan y utilizan algunos de estos métodos en una clase en Python.
Método __init__
El método __init__ se utiliza para inicializar los atributos de una clase cuando se crea una nueva instancia.
class Persona:
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
persona1 = Persona("Alice", 30)
print(persona1.nombre) # Salida: Alice
print(persona1.edad) # Salida: 30Métodos __str__ y __repr__
Los métodos __str__ y __repr__ devuelven representaciones en cadena de un objeto. La diferencia principal es que __str__ está destinado a una representación amigable para el usuario, mientras que __repr__ está orientado a los desarrolladores y debe ser más detallado.
class Persona:
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
def __str__(self):
return f"Persona: {self.nombre}, {self.edad} años"
def __repr__(self):
return f"Persona('{self.nombre}', {self.edad})"
persona1 = Persona("Alice", 30)
print(str(persona1)) # Salida: Persona: Alice, 30 años
print(repr(persona1)) # Salida: Persona('Alice', 30)Método __len__
El método __len__ se utiliza para devolver la longitud de un objeto.
class Grupo:
def __init__(self, miembros):
self.miembros = miembros
def __len__(self):
return len(self.miembros)
grupo = Grupo(["Alice", "Bob", "Charlie"])
print(len(grupo)) # Salida: 3Métodos __getitem__, __setitem__ y __delitem__
Estos métodos permiten que los objetos de una clase se comporten como contenedores (listas, diccionarios, etc.).
class MiLista:
def __init__(self):
self.data = []
def __getitem__(self, index):
return self.data[index]
def __setitem__(self, index, value):
self.data[index] = value
def __delitem__(self, index):
del self.data[index]
mi_lista = MiLista()
mi_lista.data = [1, 2, 3, 4, 5]
print(mi_lista[2]) # Salida: 3
mi_lista[2] = 30
print(mi_lista[2]) # Salida: 30
del mi_lista[2]
print(mi_lista.data) # Salida: [1, 2, 4, 5]Métodos __iter__ y __next__
Estos métodos permiten que los objetos de una clase sean iterables.
class Contador:
def __init__(self, max):
self.max = max
self.contador = 0
def __iter__(self):
return self
def __next__(self):
if self.contador < self.max:
self.contador += 1
return self.contador
else:
raise StopIteration
contador = Contador(5)
for numero in contador:
print(numero)Métodos Dunder para operaciones aritméticas
Además de los métodos mencionados, Python permite sobrecargar operadores aritméticos usando métodos dunder como __add__, __sub__, __mul__, __truediv__, entre otros.
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, otro):
return Vector(self.x + otro.x, self.y + otro.y)
def __repr__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2
print(v3) # Salida: Vector(6, 8)