Python Operator Overloading

htt‮w//:sp‬ww.theitroad.com

Operator overloading is the process of defining a special behavior for built-in operators such as +, -, *, /, %, ==, !=, <, >, <=, >=, and, or, and others when they are used with objects of user-defined classes. This allows us to use these operators with our own custom objects in a way that is natural and intuitive.

In Python, operator overloading is achieved by defining special methods in the class that correspond to the operator being overloaded. These methods are called magic methods or dunder methods (short for "double underscore" methods) because their names are enclosed in double underscores.

For example, let's say we have a class Fraction that represents a fraction with a numerator and denominator. We can define the + operator to add two fractions together by defining the __add__ method:

class Fraction:
    def __init__(self, numerator, denominator):
        self.numerator = numerator
        self.denominator = denominator

    def __add__(self, other):
        new_numerator = self.numerator * other.denominator + self.denominator * other.numerator
        new_denominator = self.denominator * other.denominator
        return Fraction(new_numerator, new_denominator)

In this example, we've defined the __add__ method to take two Fraction objects as arguments and return a new Fraction object that represents their sum. When we use the + operator with two Fraction objects, Python will automatically call this method.

We can create two Fraction objects and add them together using the + operator:

a = Fraction(1, 2)
b = Fraction(3, 4)
c = a + b
print(c.numerator, c.denominator)  # Output: 5 4

When we add a and b together with the + operator, Python calls the __add__ method that we defined in the Fraction class, which returns a new Fraction object with the sum of the two fractions. The output of the program is 5 4, which represents the fraction 5/4.

Python provides many other magic methods for operator overloading, such as __sub__ for the - operator, __mul__ for the * operator, __eq__ for the == operator, and many more. By defining these methods in our own classes, we can customize the behavior of built-in operators to work with our custom objects.