⚡IntermediateObject-Oriented Python
Special Methods (Dunder Methods)
Making objects behave like built-in types using __str__, __len__, __eq__, __add__, and more.
Overview
Special methods (also called dunder methods short for "double underscore") let your objects integrate seamlessly with Python's built-in operators and functions. When you write `len(obj)`, Python calls `obj.__len__()`. When you write `a + b`, Python calls `a.__add__(b)`. When you write `a == b`, Python calls `a.__eq__(b)`.
This protocol is how Python achieves its clean syntax everything from `print()` to `for` loops to arithmetic operators is backed by dunder methods. By implementing the right dunders in your class, you can make your objects behave exactly like built-in types.
The most useful dunders for everyday classes are: `__str__` and `__repr__` for display, `__len__` for `len()`, `__eq__` and comparison operators, `__add__`/`__sub__`/etc. for arithmetic, `__getitem__`/`__setitem__` for indexing, and `__iter__`/`__next__` for iteration.
Key Points
- •`__str__(self)` → called by print() and str() human-readable output
- •`__repr__(self)` → called in the REPL and repr() unambiguous, developer-facing output
- •`__len__(self)` → called by len() return an integer
- •`__eq__(self, other)` → called by ==; `__lt__`, `__le__`, `__gt__`, `__ge__` for comparisons
- •`__add__`, `__sub__`, `__mul__`, `__truediv__` → arithmetic operators
- •`__getitem__(self, key)` → enables obj[key]; `__setitem__` enables obj[key] = value
- •`__contains__(self, item)` → enables `item in obj`; `__iter__` enables `for x in obj`
Examples
__str__, __repr__, __len__, __eq__
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self): # print(p) → "Point(2, 3)"
return f"Point({self.x}, {self.y})"
def __repr__(self): # repr(p) → "Point(x=2, y=3)"
return f"Point(x={self.x}, y={self.y})"
def __eq__(self, other): # p1 == p2
if not isinstance(other, Point):
return NotImplemented
return self.x == other.x and self.y == other.y
def __len__(self): # len(p) → distance in whole units
return int((self.x**2 + self.y**2) ** 0.5)
p1 = Point(3, 4)
p2 = Point(3, 4)
p3 = Point(1, 2)
print(p1) # Point(3, 4)
print(repr(p1)) # Point(x=3, y=4)
print(p1 == p2) # True
print(p1 == p3) # False
print(len(p1)) # 5Arithmetic operators and __add__
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __mul__(self, scalar): # v * 3
return Vector(self.x * scalar, self.y * scalar)
def __rmul__(self, scalar): # 3 * v (right-side multiplication)
return self.__mul__(scalar)
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2) # Vector(4, 6)
print(v1 * 3) # Vector(3, 6)
print(3 * v1) # Vector(3, 6)__getitem__ and __iter__ making a class iterable
class NumberRange:
def __init__(self, start, end):
self.data = list(range(start, end))
def __len__(self):
return len(self.data)
def __getitem__(self, index): # allows: obj[i], obj[1:3]
return self.data[index]
def __contains__(self, item): # allows: item in obj
return item in self.data
r = NumberRange(1, 6)
print(len(r)) # 5
print(r[0]) # 1
print(r[-1]) # 5
print(3 in r) # True
print(list(r)) # [1, 2, 3, 4, 5] iterable via __getitem__
for n in r:
print(n, end=" ") # 1 2 3 4 5Common Mistakes
- Defining __eq__ but not __hash__ Python sets __hash__ to None, making the object unhashable (can't be used in sets or as dict keys). Define both or use @dataclass.
- Returning the wrong type from dunders __len__ must return an int, __bool__ must return a bool
- Confusing __str__ and __repr__: __str__ is for users, __repr__ is for developers. If only one is defined, Python falls back from __str__ to __repr__.
Note
Use `@functools.total_ordering` to get all comparison operators from just `__eq__` and one of `__lt__`, `__le__`, `__gt__`, `__ge__`. Defining all six manually is tedious and error-prone.
Exercises
Write Python code to solve each exercise. Run it in your browser and check your output.
Loading editor…
Completed: 0 / 5 exercises
Knowledge Check
Question 1 of 4