metodos-dunder-python

Métodos Dunder en Python

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étodoDescripció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: 30

Mé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: 3

Mé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)