Introduction 🌟
**Magic Methods**, also known as **Dunder Methods** (because they start and end with double underscores), allow Python classes to behave like built-in types. These methods automatically get triggered on certain operations like printing, adding objects, comparing, indexing, etc.
Note
💡 Magic methods make custom classes more powerful and Pythonic
💡 They provide operator overloading, object representation, iteration behavior, and more
1. Categories of Magic Methods 🧱
- 📌 Constructor & Initialization Methods
- 📌 Representation Methods
- 📌 Arithmetic & Comparison Operators
- 📌 Container & Iterable Methods
- 📌 Attribute Access Methods
- 📌 Object Lifecycle Methods
2. Constructor: __init__ 🏗️
init_demo.py
class Person:
def __init__(self, name):
self.name = name
p = Person("Sathish")✔ Called automatically when an object is created
3. Object Representation: __str__ & __repr__ 📝
str_repr_demo.py
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"({self.x}, {self.y})"
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
p = Point(3, 4)
print(p) # __str__
print(repr(p)) # __repr__✔ __str__ → user-friendly
✔ __repr__ → developer-friendly
4. Arithmetic Magic Methods ➕➖✖️➗
arithmetic_magic.py
class Number:
def __init__(self, value):
self.value = value
def __add__(self, other):
return Number(self.value + other.value)
def __sub__(self, other):
return Number(self.value - other.value)
n1 = Number(10)
n2 = Number(5)
print((n1 + n2).value)
print((n1 - n2).value)✔ Enables operator overloading
5. Comparison Magic Methods 🔍
comparison_magic.py
class Student:
def __init__(self, marks):
self.marks = marks
def __eq__(self, other):
return self.marks == other.marks
def __lt__(self, other):
return self.marks < other.marks
s1 = Student(85)
s2 = Student(90)
print(s1 == s2)
print(s1 < s2)✔ Lets objects be compared with ==, <, etc.
6. Magic Methods for Built-in Functions 💡
len_contains_getitem.py
class Team:
def __init__(self, members):
self.members = members
def __len__(self):
return len(self.members)
def __contains__(self, item):
return item in self.members
def __getitem__(self, index):
return self.members[index]
t = Team(["A", "B", "C"])
print(len(t))
print("A" in t)
print(t[1])✔ Supports len(), in, indexing, etc.
✔ Makes objects behave like containers
7. Attribute Access Magic Methods 🔧
attribute_magic.py
class Demo:
def __getattr__(self, name):
return f"{name} not found"
def __setattr__(self, name, value):
print(f"Setting {name} = {value}")
super().__setattr__(name, value)
d = Demo()
d.x = 10
print(d.y)✔ Intercept attribute access & assignment
✔ Useful for validation & debugging
8. Iteration Magic Methods 🔄
iteration_magic.py
class Counter:
def __init__(self, limit):
self.limit = limit
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current < self.limit:
num = self.current
self.current += 1
return num
raise StopIteration
c = Counter(3)
for i in c:
print(i)✔ Enables objects to act as iterators
9. Object Lifecycle Magic Methods 🧬
lifecycle_magic.py
class Sample:
def __init__(self):
print("Object created")
def __del__(self):
print("Object destroyed")
s = Sample()
del s✔ __del__ called when object is deleted
10. Callable Objects: __call__ 📞
call_magic.py
class Greeter:
def __call__(self, name):
return f"Hello, {name}"
g = Greeter()
print(g("Sathish"))✔ Makes an object behave like a function
11. Full Example — Complete Magic Method Class 🎁
full_magic_example.py
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"({self.x}, {self.y})"
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __len__(self):
return abs(self.x) + abs(self.y)
v1 = Vector(2, 3)
v2 = Vector(1, 4)
print(v1)
print(v1 + v2)
print(len(v1))✔ Class behaves like native Python data type
12. Common Magic Methods Reference Table 📘
| Category | Magic Method | Usage |
|---|---|---|
| Constructor | __init__ | Initialize object |
| String | __str__, __repr__ | String representations |
| Arithmetic | __add__, __sub__, __mul__ | Operator overloading |
| Comparison | __eq__, __lt__, __gt__ | Comparing objects |
| Container | __len__, __getitem__, __contains__ | List-like behavior |
| Iteration | __iter__, __next__ | Iterator behavior |
| Callable | __call__ | Make object callable |
| Lifecycle | __del__ | Destruction of object |
Best Practices 💡
- ✔ Use magic methods to make classes intuitive & pythonic
- ✔ Ensure overloaded operators behave logically
- ✔ Keep method implementations simple & readable
- ✔ Avoid overusing magic methods — use only when needed
Conclusion 🎉
You now fully understand Magic / Dunder Methods in Python! Want the next topic? Try Method Overloading, Callable Objects, Iterable Protocol, or Advanced OOP. Just tell me! 😊