Magic Methods in Python
Magic methods in Python, also known as dunder (double underscore) methods, are special methods that allow objects to interact with built-in operations like addition, comparison, string representation, and more. These methods start and end with double underscores, such as __init__, __str__, and __add__. Magic methods define how objects behave in different scenarios.
Commonly Used Magic Methods
| Method | Purpose |
|---|---|
__init__ | Initializes a new instance of a class. |
__str__ | Returns a user-friendly string representation of an object. |
__repr__ | Returns an official string representation of an object. |
__len__ | Defines behavior for len() function. |
__add__ | Defines behavior for + operator. |
__eq__ | Defines behavior for == operator. |
Examples
1. Using __init__ to Initialize Objects
The __init__ method is called automatically when a new object is created. It is used to set up the object’s attributes.
In this example, we define a class Person that takes a name and age as arguments. When we create a new Person object, the __init__ method assigns these values to the object’s attributes.
class Person:
def __init__(self, name, age):
self.name = name # Assign name to the object
self.age = age # Assign age to the object
# Creating an object of the Person class
p1 = Person("Arjun", 25)
# Printing object attributes
print("Name:", p1.name)
print("Age:", p1.age)
Output:
Name: Arjun
Age: 25
The __init__ method ensures that every time we create a Person object, it is initialized with a name and age.
2. Using __str__ to Define a Readable String Representation
The __str__ method allows us to define how an object is represented as a string when printed. Without this method, printing an object would return an unhelpful memory address.
Here, we modify our Person class to include __str__. This method returns a string describing the person.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
p1 = Person("Ram", 30)
print(p1) # Calls __str__ method
Output:
Person(name=Ram, age=30)
Now, when we print the object, we get a readable representation instead of a generic memory address.
3. Using __add__ for Custom Addition
The __add__ method allows us to define how two objects should be added using the + operator.
In this example, we create a class Vector that represents a mathematical vector with an x and y component. By defining __add__, we allow two vectors to be added together using +.
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 __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(1, 4)
result = v1 + v2 # Calls __add__ method
print(result)
Output:
Vector(3, 7)
The __add__ method adds the x and y values of two vectors and returns a new Vector object.
4. Handling Errors When Using Magic Methods
If we try to add objects of different types, Python raises a TypeError. We can modify __add__ to handle this error.
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
if not isinstance(other, Vector):
raise TypeError("Can only add Vector to another Vector")
return Vector(self.x + other.x, self.y + other.y)
v1 = Vector(2, 3)
try:
result = v1 + 5 # Trying to add an integer
except TypeError as e:
print("Error:", e)
Output:
Error: Can only add Vector to another Vector
We check if other is a Vector. If not, a TypeError is raised, preventing invalid operations.
