Magic methods in Python, also known as dunder methods (short for “double underscore”), are special methods with double underscores at the beginning and end of their names. These methods allow you to define how objects of your classes behave with Python’s built-in operations such as addition, subtraction, comparison, and more. Magic methods are a key part of Python’s object-oriented programming (OOP) capabilities.
1. Common Magic Methods
Below are some of the most commonly used magic methods in Python:
1.1. __init__(self, ...)
The __init__
method, known as the constructor, is called when an instance of a class is created. It allows you to initialize the object’s attributes.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 30)
print(p.name, p.age)
1.2. __str__(self)
and __repr__(self)
The __str__
method is called by the str()
and print()
functions to get a readable string representation of the object, while the __repr__
method is used by the repr()
function and in the interactive interpreter for a more formal string representation.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"{self.name}, {self.age} years old"
def __repr__(self):
return f"Person(name={self.name}, age={self.age})"
p = Person("Alice", 30)
print(p) # Calls __str__()
print(repr(p)) # Calls __repr__()
1.3. __len__(self)
The __len__
method is called by the len()
function to return the length of an object.
class MyList:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
my_list = MyList([1, 2, 3, 4])
print(len(my_list))
1.4. __add__(self, other)
The __add__
method allows you to define the behavior of the +
operator for your objects.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __repr__(self):
return f"Point({self.x}, {self.y})"
p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = p1 + p2 # Calls __add__()
print(p3)
1.5. __eq__(self, other)
The __eq__
method allows you to define the behavior of the equality operator ==
for your objects.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return self.x == other.x and self.y == other.y
p1 = Point(1, 2)
p2 = Point(1, 2)
print(p1 == p2) # Calls __eq__()
1.6. __getitem__(self, key)
The __getitem__
method is used to get an item from an object using the indexing syntax.
class MyList:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
my_list = MyList([10, 20, 30, 40])
print(my_list[2]) # Calls __getitem__()
1.7. __setitem__(self, key, value)
The __setitem__
method is used to set the value of an item using the indexing syntax.
class MyList:
def __init__(self, items):
self.items = items
def __setitem__(self, index, value):
self.items[index] = value
my_list = MyList([10, 20, 30, 40])
my_list[2] = 50 # Calls __setitem__()
print(my_list.items)
1.8. __delitem__(self, key)
The __delitem__
method is used to delete an item using the indexing syntax.
class MyList:
def __init__(self, items):
self.items = items
def __delitem__(self, index):
del self.items[index]
my_list = MyList([10, 20, 30, 40])
del my_list[2] # Calls __delitem__()
print(my_list.items)
2. Other Useful Magic Methods
__call__(self, ...)
: Allows an object to be called as a function.__contains__(self, item)
: Called by thein
operator to check membership.__iter__(self)
and__next__(self)
: Used to make an object iterable.__enter__(self)
and__exit__(self, exc_type, exc_val, exc_tb)
: Used to define the behavior of a context manager (used inwith
statements).__bool__(self)
: Allows you to define the behavior of your object when it is used in a Boolean context (e.g., inif
statements).__hash__(self)
: Defines the hash value for an object, used in hashing operations like when adding an object to a set or using it as a dictionary key.