✨ Python Dunder Methods Guide
Beginner-friendly documentation about Python dunder methods (magic methods), special object behavior, and common object-oriented patterns.
📚 Table of Contents
- 📖 What are Dunder Methods?
- 🚀 init
- 🖨️ str
- 🔍 repr
- 📏 len
- ⚖️ eq
- ➕ add
- 📦 getitem
- 🔄 iter
- 🎮 Real 42 Examples
- ⚠️ Common Beginner Mistakes
- 📚 Best Practices
- 📚 Final Notes
📖 What are Dunder Methods?
Dunder methods are: - special Python methods - surrounded by double underscores
Example:
__init__
The word:
dunder
means:
double underscore
Why Dunder Methods Exist
They allow Python objects to: - behave like built-in types - customize operators - customize printing - customize comparisons - support iteration
🚀 init
__init__ runs automatically when an object is created.
Used for: - initializing attributes - preparing object state
Example
class Player:
def __init__(self, name):
self.name = name
Creating the Object
player = Player("Sara")
🖨️ str
__str__ controls:
- readable object printing
Example
class Player:
def __init__(self, name):
self.name = name
def __str__(self):
return f"Player({self.name})"
Using str
player = Player("Sara")
print(player)
Output:
Player(Sara)
Why str is Useful
Without __str__, Python prints:
<object at 0x123456>
which is not very readable.
🔍 repr
__repr__ provides:
- developer/debug representation
Example
class Enemy:
def __repr__(self):
return "Enemy()"
Difference Between str and repr
| Method | Purpose |
|---|---|
__str__ |
User-friendly output |
__repr__ |
Developer/debug output |
📏 len
__len__ controls:
- object length behavior
Example
class Inventory:
def __init__(self):
self.items = ["Sword", "Potion"]
def __len__(self):
return len(self.items)
Using len()
inventory = Inventory()
print(len(inventory))
Output:
2
⚖️ eq
__eq__ controls:
- equality comparison
Example
class Player:
def __init__(self, score):
self.score = score
def __eq__(self, other):
return self.score == other.score
Using Equality
player1 = Player(10)
player2 = Player(10)
print(player1 == player2)
Output:
True
➕ add
__add__ customizes:
- the + operator
Example
class Coins:
def __init__(self, amount):
self.amount = amount
def __add__(self, other):
return Coins(self.amount + other.amount)
Using +
c1 = Coins(5)
c2 = Coins(10)
result = c1 + c2
📦 getitem
__getitem__ allows:
- indexing with []
Example
class Inventory:
def __init__(self):
self.items = ["Sword", "Potion"]
def __getitem__(self, index):
return self.items[index]
Using Indexing
inventory = Inventory()
print(inventory[0])
Output:
Sword
🔄 iter
__iter__ allows:
- iteration with loops
Example
class Inventory:
def __init__(self):
self.items = ["Sword", "Potion"]
def __iter__(self):
return iter(self.items)
Using Iteration
for item in inventory:
print(item)
🎮 Real 42 Examples
Maze String Representation
def __str__(self):
Useful for: - ASCII maze printing
Position Comparison
def __eq__(self, other):
Useful for: - coordinate comparison - pathfinding
Inventory Length
def __len__(self):
Useful for: - item systems
Custom Containers
def __getitem__(self, index):
Useful for: - grid systems - tile access
⚠️ Common Beginner Mistakes
❌ Returning Wrong Types
Bad:
def __len__(self):
return "five"
__len__ must return:
- integer
❌ Forgetting other in eq
Wrong:
def __eq__(self):
Correct:
def __eq__(self, other):
❌ Overcomplicating Dunder Methods
Keep behavior: - simple - predictable - readable
❌ Forgetting Return Values
Example:
def __str__(self):
print("Player")
Wrong because:
- __str__ must RETURN a string
📚 Best Practices
- Keep dunder methods simple
- Return correct types
- Use dunder methods only when useful
- Avoid unnecessary operator overloads
- Focus on readability
🧠 Why Dunder Methods Matter
Dunder methods help objects: - behave naturally - integrate with Python syntax - support built-in operations - feel more flexible
They are heavily used in: - frameworks - libraries - games - APIs - custom containers
📚 Final Notes
Dunder methods are one of the most powerful features of Python OOP.
Understanding them helps create: - cleaner APIs - more intuitive objects - reusable systems - better project architecture
They become increasingly useful in larger and more advanced Python projects.