5 Useful Dunder Methods In Python
In this guide, we'll explore five of the most useful Dunder (double underscore) methods in Python. These methods provide powerful functionality for customizing the behavior of classes in Python.
Dunder Method 1: __eq__
The __eq__
method allows us to define custom equality comparison between objects of our class. By default, Python's comparison operator compares memory addresses. However, by defining __eq__
, we can compare objects based on their attributes.
class Fruit:
def __init__(self, name, grams):
self.name = name
self.grams = grams
def __eq__(self, other):
return self.__dict__ == other.__dict__
# Example usage:
apple1 = Fruit("apple", 100)
apple2 = Fruit("apple", 100)
orange = Fruit("orange", 150)
print(apple1 == apple2) # Output: True
print(apple1 == orange) # Output: False
Dunder Method 2: __format__
The __format__
method allows us to define custom formatting when using the format()
function or f-strings. We can specify different formats for our objects.
class Fruit:
def __init__(self, name, grams):
self.name = name
self.grams = grams
def __format__(self, format_spec):
if format_spec == "kg":
return f"{self.grams / 1000:.2f} kg"
elif format_spec == "lbs":
return f"{self.grams * 0.00220462:.2f} lbs"
elif format_spec == "description":
return f"{self.name.capitalize()} weighing {self.grams} grams"
else:
raise ValueError("Unsupported format specifier")
# Example usage:
apple = Fruit("apple", 2500)
print(f"{apple:kg}") # Output: 2.50 kg
print(f"{apple:lbs}") # Output: 5.51 lbs
print(f"{apple:description}") # Output: Apple weighing 2500 grams
Dunder Method 3: __or__
The __or__
method allows us to define custom behavior for combining objects using the |
operator. This is particularly useful for creating composite objects.
class Fruit:
def __init__(self, name, grams):
self.name = name
self.grams = grams
def __or__(self, other):
return Fruit(self.name + ' & ' + other.name, self.grams + other.grams)
# Example usage:
apple = Fruit("apple", 100)
orange = Fruit("orange", 150)
banana = Fruit("banana", 200)
combined = apple | orange | banana
print(combined.name) # Output: apple & orange & banana
print(combined.grams) # Output: 450
Dunder Method 4: __str__ and __repr__
The __str__
and __repr__
methods allow us to define custom string representations for our objects. __str__
is meant for user-friendly output, while __repr__
is for developer-oriented output.
class Fruit:
def __init__(self, name, grams):
self.name = name
self.grams = grams
def __str__(self):
return f"{self.name} ({self.grams}g)"
def __repr__(self):
return f"Fruit(name='{self.name}', grams={self.grams})"
# Example usage:
apple = Fruit("apple", 100)
print(str(apple)) # Output: apple (100g)
print(repr(apple)) # Output: Fruit(name='apple', grams=100)
Dunder Method 5: __getitem__
The __getitem__
method allows us to make our objects subscriptable, enabling access by index or key.
class Basket:
def __init__(self, fruits):
self.fruits = fruits
def __getitem__(self, item):
return [fruit for fruit in self.fruits if fruit.name.lower() == item.lower()]
# Example usage:
fruits = [Fruit("apple", 100), Fruit("orange", 150), Fruit("banana", 200)]
basket = Basket(fruits)
print(basket["orange"]) # Output: [orange (150g)]
These Dunder methods provide powerful customization capabilities, allowing you to tailor the behavior of your classes to suit your specific needs in Python.