Introduction
Python is known for its simplicity and powerful Object-Oriented Programming (OOP) features. One of the most interesting OOP concepts in Python is Magic Methods. These special methods allow developers to define how objects behave with built-in Python operations such as addition, comparison, printing, object creation, and much more.
Magic methods are also called:
- Dunder Methods (Double Underscore Methods)
- Special Methods
They are called dunder methods because their names begin and end with double underscores (__).
For example:
__init__()
__str__()
__len__()
__add__()
These methods are automatically called by Python when certain operations are performed on objects.
For instance, when you create an object:
student = Student()
Python automatically calls:
__init__()
Similarly, when you print an object:
print(student)
Python automatically calls:
__str__()
Magic methods enable operator overloading, custom object behavior, cleaner code, and greater flexibility. They are heavily used in Python libraries, frameworks, and real-world applications.
In this article, you’ll learn what magic methods are, how they work, their syntax, common examples, real-life use cases, common mistakes, interview questions, and best practices.
What are Magic Methods in Python?
Magic methods are predefined methods in Python that start and end with double underscores.
They allow objects to interact with Python’s built-in functions and operators.
Example:
class Student:
def __init__(self, name):
self.name = name
Here: __init__() is a magic method.
Python automatically executes it when an object is created.
Syntax
Basic syntax:
class ClassName:
def __magic_method__(self):
pass
Example:
class Student:
def __init__(self, name):
self.name = name
The init() Method
The most commonly used magic method is:
__init__()
It acts as a constructor.
Example:
class Student:
def __init__(self, name):
self.name = name
student = Student("John")
print(student.name)
Output:
Explanation:
Python automatically calls __init__() when the object is created.
The str() Method
The __str__() method defines how an object is displayed as a string.
Example:
class Student:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
student = Student("John")
print(student)
Output:
Without __str__(), Python displays a memory address.
The repr() Method
__repr__() provides an official string representation of an object.
Example:
class Student:
def __repr__(self):
return "Student Object"
Usage:
student = Student()
print(student)
Output:
__repr__() is mainly used for debugging.
The len() Method
Defines behavior for:
len(object)
Example:
class Students:
def __len__(self):
return 50
students = Students()
print(len(students))
Output:
The add() Method
Used for the + operator.
Example:
class Number:
def __init__(self, value):
self.value = value
def __add__(self, other):
return self.value + other.value
num1 = Number(10)
num2 = Number(20)
print(num1 + num2)
Output:
This is called operator overloading.
The sub() Method
Used for subtraction.
Example:
class Number:
def __init__(self, value):
self.value = value
def __sub__(self, other):
return self.value - other.value
num1 = Number(30)
num2 = Number(10)
print(num1 - num2)
Output:
The mul() Method
Used for multiplication.
Example:
class Number:
def __init__(self, value):
self.value = value
def __mul__(self, other):
return self.value * other.value
num1 = Number(5)
num2 = Number(4)
print(num1 * num2)
Output:
Comparison Magic Methods
Python allows custom comparison behavior.
eq()
Used for equality.
Example:
class Student:
def __init__(self, marks):
self.marks = marks
def __eq__(self, other):
return self.marks == other.marks
s1 = Student(90)
s2 = Student(90)
print(s1 == s2)
Output:
Other Comparison Methods
| Method | Operator |
|---|---|
| __eq__() | == |
| __ne__() | != |
| __lt__() | < |
| __gt__() | > |
| __le__() | <= |
| __ge__() | >= |
The contains() Method
Used with the in operator.
Example:
class MyList:
def __contains__(self, item):
return item == 10
obj = MyList()
print(10 in obj)
Output:
The getitem() Method
Allows indexing behavior.
Example:
class Numbers:
def __getitem__(self, index):
data = [10, 20, 30]
return data[index]
obj = Numbers()
print(obj[1])
Output:
The setitem() Method
Handles assignment through indexing.
Example:
class Data:
def __setitem__(self, key, value):
print(key, value)
obj = Data()
obj[0] = 100
Output:
The call() Method
Makes an object callable like a function.
Example:
class Student:
def __call__(self):
print("Object Called")
student = Student()
student()
Output:
The del() Method
Called when an object is destroyed.
Example:
class Student:
def __del__(self):
print("Object Deleted")
student = Student()
del student
Output:
Common Magic Methods Table
| Method | Operator |
|---|---|
| __init__() | Constructor |
| __str__() | String representation |
| __repr__() | Official representation |
| __len__() | Length |
| __add__() | Addition |
| __sub__() | Subtraction |
| __mul__() | Multiplication |
| __eq__() | Equality comparison |
| __getitem__() | Indexing |
| __setitem__() | Item assignment |
| __contains__() | Membership testing |
| __call__() | Function call behavior |
| __del__() | Object destruction |
Real-Life Examples:
1. Shopping Cart
class Cart:
def __init__(self):
self.items = []
def __len__(self):
return len(self.items)
cart = Cart()
cart.items.append("Laptop")
cart.items.append("Mouse")
print(len(cart))
Output:
The cart behaves like a built-in collection.
2. Employee Comparison
class Employee:
def __init__(self, salary):
self.salary = salary
def __gt__(self, other):
return self.salary > other.salary
emp1 = Employee(50000)
emp2 = Employee(40000)
print(emp1 > emp2)
Output:
Custom comparison behavior is implemented.
Magic Methods and Operator Overloading
Magic methods make operator overloading possible.
Example:
print(5 + 3)
Internally:
5.__add__(3)
Similarly:
num1 + num2
calls:
num1.__add__(num2)
This allows custom objects to work with operators.
Advantages of Magic Methods
| Advantage | Description |
|---|---|
| Cleaner Syntax | Natural object behavior |
| Operator Overloading | Customize operators |
| Better Readability | Easier-to-understand code |
| Python Integration | Works with built-in functions |
| Flexibility | Powerful customization |
Common Mistakes
1. Calling Magic Methods Directly
Incorrect:
obj.__add__(other)
Better:
obj + other
2. Forgetting Return Statements
Incorrect:
def __str__(self):
print("Student")
Correct:
def __str__(self):
return "Student"
3. Using del() for Critical Cleanup
Garbage collection timing is unpredictable.
Avoid relying on:
__del__()
for important operations.
4. Returning Wrong Types
Incorrect:
def __len__(self):
return "10"
Correct:
def __len__(self):
return 10
5. Overusing Operator Overloading
Only overload operators when it makes logical sense.
Conclusion
Magic methods are one of Python’s most powerful Object-Oriented Programming features. They allow developers to customize object behavior and seamlessly integrate custom classes with Python’s built-in functions, operators, and language features.
From constructors like __init__() to operator overloading methods such as __add__() and comparison methods like __eq__(), magic methods make Python classes more intuitive, readable, and flexible.
By understanding and using magic methods effectively, developers can create professional, reusable, and highly maintainable Python applications that behave just like native Python objects.
Python Magic Methods – Interview Questions
Q 1: What are magic methods in Python?
Q 2: What is the purpose of __init__()?
Q 3: What does __str__() do?
Q 4: Can magic methods be called directly?
Q 5: Name other common magic methods.
Python Magic Methods – Objective Questions (MCQs)
Q1. What are magic methods in Python?
Q2. Which magic method is called when an object is created?
Q3. What is the purpose of the __str__() magic method?
Q4. Which magic method is used to define the behavior of the + operator for objects?
Q5. What will the following code print?
class Demo:
def __len__(self):
return 5
obj = Demo()
print(len(obj))