What are Dunder Methods?
Dunder methods (short for "double underscore") are special methods in Python that allow you to define how objects behave with built-in operations. They're also known as "magic methods" or "special methods".
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 __repr__(self):
return f"Vector({self.x}, {self.y})"
1. Object Lifecycle Methods
Methods called during object creation, initialization, and destruction.
| Dunder Method | Called When | Common Usage |
|---|---|---|
| Basic __new__ | Creating a new instance (before __init__) | Singleton pattern, immutable objects, metaclasses |
| Basic __init__ | Object initialization after creation | Setting initial attributes, validation |
| Basic __del__ | Object is about to be destroyed | Cleanup operations, closing resources |
| Advanced __init_subclass__ | A subclass is created | Plugin systems, registering subclasses |
External Reference
Python Documentation: Object Initialization - Official documentation on object creation and initialization.
2. String & Representation Methods
Methods for converting objects to strings and representations.
| Dunder Method | Called When | Return Value Should Be |
|---|---|---|
| Basic __str__ | print(obj), str(obj), f-strings | Informal, human-readable string |
| Basic __repr__ | repr(obj), debugging, console | Unambiguous, official string representation |
| Basic __format__ | format(obj), f-strings with format spec | Formatted string according to spec |
| Advanced __bytes__ | bytes(obj) is called | Byte representation of object |
External Reference
W3Schools: String Representation - Tutorial on __str__ vs __repr__ with examples.
3. Arithmetic Operator Methods
Methods for overriding arithmetic operations like +, -, *, /, etc.
| Dunder Method | Operation | Reverse Method |
|---|---|---|
| Arithmetic __add__ | obj1 + obj2 | __radd__ |
| Arithmetic __sub__ | obj1 - obj2 | __rsub__ |
| Arithmetic __mul__ | obj1 * obj2 | __rmul__ |
| Arithmetic __truediv__ | obj1 / obj2 | __rtruediv__ |
| Arithmetic __floordiv__ | obj1 // obj2 | __rfloordiv__ |
| Arithmetic __mod__ | obj1 % obj2 | __rmod__ |
| Arithmetic __pow__ | obj1 ** obj2 or pow(obj1, obj2) | __rpow__ |
| Advanced __matmul__ | obj1 @ obj2 (Python 3.5+) | __rmatmul__ |
External Reference
GeeksforGeeks: Operator Overloading - Comprehensive guide to operator overloading in Python.
4. Comparison Operator Methods
Methods for overriding comparison operations like ==, <, >, etc.
| Dunder Method | Operation | Complement Method |
|---|---|---|
| Comparison __eq__ | obj1 == obj2 | __ne__ (if not defined) |
| Comparison __ne__ | obj1 != obj2 | Auto from __eq__ if not defined |
| Comparison __lt__ | obj1 < obj2 | Used for sorting |
| Comparison __le__ | obj1 <= obj2 | Less than or equal |
| Comparison __gt__ | obj1 > obj2 | Greater than |
| Comparison __ge__ | obj1 >= obj2 | Greater than or equal |
Tip: Define __lt__ and __eq__, and use the @functools.total_ordering decorator to automatically get all comparison operators.
5. Container & Iteration Methods
Methods for making objects behave like containers (lists, dicts) or iterables.
| Dunder Method | Called When | Common Use Case |
|---|---|---|
| Container __len__ | len(obj) is called | Containers, collections |
| Container __getitem__ | obj[key] or obj[index] | Indexing, slicing |
| Container __setitem__ | obj[key] = value | Mutable containers |
| Container __delitem__ | del obj[key] | Removing items |
| Container __iter__ | iter(obj), for loops | Making objects iterable |
| Container __next__ | next(iterator) | Iterator protocol |
| Container __contains__ | item in obj | Membership testing |
| Advanced __reversed__ | reversed(obj) | Reverse iteration |
6. Context Manager Methods
Methods for creating objects that work with the with statement.
| Dunder Method | Called When | Example Usage |
|---|---|---|
| Context __enter__ | Entering a with block |
Opening files, acquiring locks |
| Context __exit__ | Exiting a with block |
Closing resources, handling exceptions |
| Context __call__ | obj() is invoked | Making objects callable like functions |
| Advanced __aenter__ | Entering async async with |
Async context managers |
| Advanced __aexit__ | Exiting async async with |
Async context managers |
External Reference
RealPython: Context Managers - Deep dive into context managers and the with statement.
7. Advanced & Special Methods
Specialized methods for advanced Python features and optimizations.
| Dunder Method | Purpose | Python Version |
|---|---|---|
| Advanced __getattr__ | Access missing attribute | All versions |
| Advanced __setattr__ | Set any attribute | All versions |
| Advanced __getattribute__ | Access any attribute (all) | All versions |
| Advanced __hash__ | hash(obj), dict keys, sets | All versions |
| Advanced __bool__ | bool(obj), if obj, while obj | All versions |
| Advanced __dir__ | dir(obj), tab completion | All versions |
| Advanced __getstate__ | pickle.dump(obj) | All versions |
| Advanced __setstate__ | pickle.load(obj) | All versions |
| Advanced __slots__ | Memory optimization | All versions |
External Reference
Python Docs: Special Method Names - Complete official list of all special methods.
Summary & Best Practices
When to Use Dunder Methods
- Creating domain-specific languages
- Implementing mathematical objects
- Making custom containers
- Resource management with context managers
Common Pitfalls
- Not implementing reverse methods (__radd__, etc.)
- Forgetting to return NotImplemented for unsupported types
- Infinite recursion in __getattribute__
- Not preserving hash immutability