Lección 10 · 10 de 20
Métodos especiales · Python
Haga que sus objetos se escriban, comparen, sumen y midan como los de Python con __repr__, __eq__, __lt__, __add__ y __len__.

Los métodos especiales (o *dunder*, por los dos guiones bajos) son los que Python llama por su cuenta cuando usa operadores y funciones integradas. Money guarda el importe en céntimos (cents), un entero, para no arrastrar errores de redondeo.
`__repr__` devuelve el texto que representa al objeto. Se usa en print() cuando no hay __str__ y, sobre todo, dentro de listas: por eso cart.prices sale como [19.99 EUR, 4.50 EUR, 120.00 EUR] y no como direcciones de memoria.
`__eq__` define ==: compara importe y moneda como una tupla. Sin él, dos Money(450) serían distintos porque son objetos diferentes. `__lt__` define <, y con eso basta para que sorted(), min() y max() sepan ordenar.
`__add__` define + y devuelve un Money nuevo. Gracias a él funciona sum(cart.prices, Money(0)): sum empieza en el segundo argumento (que debe ser un Money, no el 0 por defecto) y va sumando con +. Si las monedas no coinciden, lanza ValueError.
En Cart, `__len__` hace que len(cart) funcione. Hay muchos más: __getitem__ para cart[0], __contains__ para in, __bool__ para if cart:…
Código · main.py
class Money: def __init__(self, cents, currency="EUR"): self.cents = cents self.currency = currency def __repr__(self): # how it prints, also inside lists return f"{self.cents / 100:.2f} {self.currency}" def __eq__(self, other): # == return (self.cents, self.currency) == (other.cents, other.currency) def __lt__(self, other): # < (and so sorted, min, max) return self.cents < other.cents def __add__(self, other): # + if self.currency != other.currency: raise ValueError("cannot add different currencies") return Money(self.cents + other.cents, self.currency)class Cart: def __init__(self, *prices): self.prices = list(prices) def __len__(self): # len(cart) return len(self.prices)cart = Cart(Money(1999), Money(450), Money(12000))print("Items:", len(cart), cart.prices)print("Total:", sum(cart.prices, Money(0)))print("Sorted:", sorted(cart.prices))print("Equal:", Money(450) == Money(450), "| less:", Money(450) < Money(1999))try: Money(100) + Money(100, "USD")except ValueError as error: print("Error:", error)Salida · python3 main.py
Items: 3 [19.99 EUR, 4.50 EUR, 120.00 EUR] Total: 144.49 EUR Sorted: [4.50 EUR, 19.99 EUR, 120.00 EUR] Equal: True | less: True Error: cannot add different currencies
Para recordar
- Python llama a los métodos especiales por usted:
+llama a__add__. __repr__es la representación; procure que sea clara.__eq__define==y__lt__basta para ordenar.__len__hace funcionarlen().- Guardar el dinero en céntimos enteros evita errores de redondeo.
Ejercicio
Añada __mul__ a Money para que Money(1999) * 3 devuelva 59.97 EUR, y úselo para cobrar tres unidades del primer artículo.