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.