Placement Prep

Operator Overloading in Python: Magic Methods with Examples

How Python maps +, -, == and other operators to dunder methods like __add__ and __lt__. Covers the full magic-method table plus two worked placement-style examples.

By FACE Prep Team 4 min read
python operator-overloading magic-methods dunder-methods placement-prep python-programming oop

Operator overloading in Python means giving a custom class the ability to respond to standard operators like +, -, ==, and <, by defining dunder methods (the __method__ naming pattern).

Python’s built-in types already do this. The + operator produces three different results depending on the operand type:

  • 5 + 3 runs integer addition and returns 8.
  • 'Hello' + ' World' concatenates strings and returns 'Hello World'.
  • [1, 2] + [3, 4] merges lists and returns [1, 2, 3, 4].

Same operator symbol. Three different behaviours. That’s operator overloading. When you create a custom class, Python doesn’t know how to apply + to it by default. You teach it by defining the right dunder method.

What operator overloading means in Python

Python resolves every operator through its data model’s special method names. When Python evaluates a + b, it calls a.__add__(b). When it evaluates a < b, it calls a.__lt__(b). These methods follow the __name__ convention with two leading and two trailing _ characters, which is how Python distinguishes them from regular methods.

You can define or override these methods in any class you write. That is operator overloading: not a separate language feature, just class methods with specific names.

Here is what happens without operator overloading:

class Student:
    def __init__(self, marks1, marks2):
        self.marks1 = marks1
        self.marks2 = marks2

s1 = Student(50, 60)
s2 = Student(30, 40)
print(s1 + s2)  # TypeError

Output:

TypeError: unsupported operand type(s) for +: 'Student' and 'Student'

Python looked for Student.__add__, didn’t find it, and raised TypeError. The fix is to define __add__.

The magic-method table

Python’s data model maps every operator to a named dunder method. The tables below cover the categories that appear in placement MCQ rounds and coding problems. Full reference is in the Python 3 docs on emulating numeric types.

Arithmetic operators

OperatorDunder method
+__add__
-__sub__
*__mul__
/__truediv__
//__floordiv__
%__mod__
**__pow__

Comparison operators

OperatorDunder method
<__lt__
>__gt__
<=__le__
>=__ge__
==__eq__
!=__ne__

Assignment operators

OperatorDunder method
+=__iadd__
-=__isub__
*=__imul__
/=__itruediv__

Unary operators

OperatorDunder method
+x__pos__
-x__neg__
~x__invert__

The pattern is consistent: look up the operator, find the method, define it in your class. For context on arithmetic operators in Python, __add__ and __sub__ cover the most common cases.

Worked example: arithmetic operator overloading

Adding __add__ to the Student class makes s1 + s2 work and produce a meaningful result. It returns a new Student whose marks are the combined totals:

class Student:
    def __init__(self, marks1, marks2):
        self.marks1 = marks1
        self.marks2 = marks2

    def __add__(self, other):
        return Student(self.marks1 + other.marks1,
                       self.marks2 + other.marks2)

    def __repr__(self):
        return f'Student(marks1={self.marks1}, marks2={self.marks2})'

s1 = Student(50, 60)
s2 = Student(30, 40)
s3 = s1 + s2
print(s3)

Output:

Student(marks1=80, marks2=100)

Two things to note about this pattern:

  • __add__ returns a new Student instance. It does not modify self or other.
  • __repr__ handles display. Without it, print(s3) shows the object’s memory address, which is useless.

The other parameter gives access to the second operand’s attributes. Adding other.marks1 and other.marks2 to self.marks1 and self.marks2 follows the same logic you’d use for combining two dictionaries by summing their values. Python routes the + symbol to your method automatically.

Worked example: comparison operator overloading

Comparison operators return bool. That’s the contract every __lt__, __eq__, and related method must keep. Returning something else (an integer, None) will produce behaviour that looks correct, then breaks in sorting.

class Circle:
    def __init__(self, radius):
        self.radius = radius

    def __lt__(self, other):
        return self.radius < other.radius

    def __eq__(self, other):
        return self.radius == other.radius

c1 = Circle(5)
c2 = Circle(10)
print(c1 < c2)   # True
print(c1 == c2)  # False

Output:

True
False

The __lt__ method compares self.radius with other.radius using the built-in < for integers. The return value is a plain bool. A list of Circle objects can now be sorted with sorted() once __lt__ is defined, because Python’s sort calls __lt__ internally.

For comparison operators applied to numbers, Python handles the comparison natively. For custom objects, you define it yourself.

What to watch for

Three common mistakes in placement coding rounds:

Forgetting __repr__

Without __repr__, printing a custom object shows something like <__main__.Student object at 0x7f3c>. Define __repr__ whenever you overload operators. It takes 30 seconds and prevents confused output during debugging.

Wrong return types in comparison methods

__lt__ should return True or False, not 0 or 1. Python treats any non-zero integer as truthy, so the bug is silent. In tests that check type(c1 < c2), returning an int fails the assertion.

Asymmetric addition

a + b calls a.__add__(b). If b is a different type that doesn’t know how to add to a, Python then tries b.__radd__(a). Without __radd__, a mixed-type addition raises TypeError. In placement problems, this edge case shows up as: “What does 3 + s1 produce if s1 is a Student?” The answer is TypeError unless Student also defines __radd__.

The Python basics articles cover the foundational patterns (loops, conditionals, functions) that support writing classes like these cleanly.

Why this matters past the test

Once you know that + is __add__ and == is __eq__, Python’s built-in types stop being magic. A NumPy array responds to array1 + array2 because NumPy defined __add__ to call its C-level vectorised addition. A Pandas DataFrame responds to df1 + df2 the same way.

Building your own class (say, a Vector that supports dot-product via * or magnitude comparison via <) starts the same way the Student example did: one dunder method at a time.

The Student marks-combination built with __add__ above is the kind of small interactive class that benefits from a live REPL. TinkerLLM runs Python in the browser at ₹299, so you can experiment with custom dunder methods and see the output without a local install.

Primary sources

Frequently asked questions

Does operator overloading work for all Python operators?

Most operators have dunder method equivalents, but is, and, or, and not cannot be overloaded. They are language keywords, not operator slots in the data model.

What happens if __add__ is not defined in a custom class?

Python raises TypeError: unsupported operand type(s) for + when you use + between a custom-class instance and any other object. The fix is to define __add__ in the class.

Does __add__ need to return a new object?

Yes. The convention is to return a new instance without modifying either operand. Modifying self inside __add__ breaks expected behaviour and produces bugs that are hard to trace.

What is the difference between __add__ and __radd__?

__add__ handles self + other. __radd__ handles other + self when other does not know how to add to self. Implement __radd__ for full symmetry in numeric custom types.

Is operator overloading tested in placement exams?

Yes. MCQ rounds test which dunder method maps to which operator. Coding rounds sometimes ask you to implement a custom class that supports + or < comparisons.

Build AI projects

A self-paced playground for building with LLMs.

TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.

Try TinkerLLM (₹299 launch)
Free AI Roadmap PDF