__len__() / __getitem__() / __iter__()
Dunder methods (short for "double underscore") are special methods whose names begin and end with two underscores. They work in conjunction with built-in functions and operators, letting you give your own classes standard Python behavior. Dunder methods are rarely called directly — instead, they are invoked automatically when you use functions like len() or operators like [].
Common Dunder Methods
| Method | Description |
|---|---|
| __len__(self) | Called by the len() function. Returns the number of items as an integer. |
| __getitem__(self, key) | Called when an item is accessed with obj[key]. |
| __setitem__(self, key, val) | Called when a value is assigned with obj[key] = val. |
| __delitem__(self, key) | Called when an item is deleted with del obj[key]. |
| __iter__(self) | Called by iter() or a for loop to retrieve an iterator from the object. |
| __next__(self) | Called by next() to retrieve the next element from an iterator. |
| __contains__(self, item) | Called by the in operator, as in item in obj. |
| __eq__(self, other) | Called when two objects are compared with the == operator. |
| __lt__(self, other) | Called when two objects are compared with the < operator. |
| __add__(self, other) | Called when the + operator is used to add two objects. |
| __len__(self) | Corresponds to the len() function. |
Sample Code
class ShoppingCart:
"""A sample shopping cart class."""
def __init__(self):
self._items = []
def add(self, item, price):
self._items.append({'name': item, 'price': price})
def __len__(self):
"""Return the number of items when len(cart) is called."""
return len(self._items)
def __getitem__(self, index):
"""Return an item when cart[0] is used."""
return self._items[index]
def __setitem__(self, index, value):
"""Replace an item when cart[0] = value is used."""
self._items[index] = value
def __delitem__(self, index):
"""Remove an item when del cart[0] is used."""
del self._items[index]
def __contains__(self, name):
"""Search for an item by name when 'apple' in cart is used."""
return any(item['name'] == name for item in self._items)
def __iter__(self):
"""Allow iteration with a for loop: for item in cart."""
return iter(self._items)
def __eq__(self, other):
"""Compare two carts with the == operator."""
if not isinstance(other, ShoppingCart):
return NotImplemented
return self._items == other._items
cart = ShoppingCart()
cart.add('apple', 150)
cart.add('orange', 100)
cart.add('banana', 200)
print(len(cart)) # 3
print(cart[0]) # {'name': 'apple', 'price': 150}
print('orange' in cart) # True
print('grape' in cart) # False
for item in cart:
print(f"{item['name']}: {item['price']}")
del cart[1] # Remove orange
print(len(cart)) # 2
# Customizing comparison operators (sorting with __lt__)
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __lt__(self, other):
return self.score < other.score
def __eq__(self, other):
return self.score == other.score
def __repr__(self):
return f"Student({self.name}, {self.score})"
students = [Student('Tanaka', 75), Student('Suzuki', 90), Student('Yamada', 60)]
students.sort() # sort() works as long as __lt__ is defined
print(students) # [Student(Yamada, 60), Student(Tanaka, 75), Student(Suzuki, 90)]
Notes
Implementing dunder methods lets you add standard Python operations to your own classes. This is also known as "operator overloading." For example, implementing __add__ enables the + operator, and implementing both __iter__ and __next__ turns your class into an iterable that works in a for loop.
When implementing comparison operators, defining all of __eq__, __lt__, __le__, __gt__, and __ge__ can be tedious. In that case, the functools.total_ordering decorator lets you define just __eq__ and __lt__, and it automatically generates the remaining comparison methods.
Calling dunder methods directly is discouraged (use len(obj) instead of obj.__len__()) — this is part of Python's design philosophy. Compared to direct calls, going through a built-in function may perform additional checks such as type validation.
If you find any errors or copyright issues, please contact us.