What are dunder (magic) methods in Python?
Dunder (“double underscore”) methods — also called magic or special methods — are the methods Python calls implicitly to implement language-level behavior on your objects: operators, built-ins, iteration, context management, attribute access, and more. Their names begin and end with __ (e.g. __init__, __len__, __add__).
The data model: defining these methods opts your class into Python’s data model. Instead of calling obj.__len__(), users call len(obj); instead of a.__add__(b), they write a + b. Your class behaves like a built-in.
Common categories:
Construction & lifecycle —
__new__,__init__,__del__.String representations —
__repr__(developer-facing, aim to make it unambiguous),__str__(user-facing),__format__.Equality & ordering —
__eq__,__hash__,__lt__,__le__,__gt__,__ge__; consider@functools.total_ordering.Numeric operators —
__add__,__sub__,__mul__,__truediv__, plus reflected (__radd__) and in-place (__iadd__) variants.Containers & iteration —
__len__,__getitem__,__setitem__,__delitem__,__iter__,__next__,__contains__,__reversed__.Callable —
__call__makes an instance callable like a function.Context managers —
__enter__,__exit__forwithblocks.Attribute access —
__getattr__,__getattribute__,__setattr__,__delattr__; descriptors via__get__,__set__,__delete__.Async —
__await__,__aiter__,__anext__,__aenter__,__aexit__.Introspection & meta —
__class__,__dict__,__slots__,__init_subclass__,__set_name__
class Money:
def __init__(self, amount, currency='USD'):
self.amount = amount
self.currency = currency
def __repr__(self):
return f'Money({self.amount}, "{self.currency}")'
def __str__(self):
return f'{self.currency} {self.amount:.2f}'
def __eq__(self, other):
return self.amount == other.amount and self.currency == other.currency
def __hash__(self):
return hash((self.amount, self.currency))
def __add__(self, other):
if self.currency != other.currency:
raise ValueError('Cannot add different currencies')
return Money(self.amount + other.amount, self.currency)
def __lt__(self, other):
return self.amount < other.amount
def __bool__(self):
return self.amount != 0
def __len__(self):
return int(self.amount)
price = Money(29.99)
tax = Money(5.00)
total = price + tax # __add__
print(total) # __str__: 'USD 34.99'
print(repr(total)) # __repr__: 'Money(34.99, "USD")'
print(price == Money(29.99)) # __eq__: True
print(price < total) # __lt__: True
print(bool(Money(0))) # __bool__: False
print(sorted([total, price, tax])) # Uses __lt__Money integrates with Python syntax: + calls add, print calls str, repr calls repr, == calls eq, < calls lt, bool() calls bool. sorted() uses lt for ordering. hash enables Money as dict keys. This makes Money behave like a built-in type.
Know the most common dunder methods: init, str, repr, eq, hash, len, add, iter. The str vs repr distinction (human-readable vs developer-readable) is frequently asked.
Show operator overloading (add for +) and context manager (enter/exit for with).