REVISEALGOLEARN|PRACTICE|PROGRESS

Polymorphism & Abstraction

Operator Overloading

Custom operators for classes via dunder methods

Interview: Advanced OOP — tests understanding of Python data model and when operator overloading is appropriate

Last Updated: June 12, 2026 • 6 min read

Operator overloading lets you define how built-in operators (+, -, *, ==, <, etc.) work with your custom objects. It's implemented through dunder methods. When used appropriately, it makes custom classes feel like built-in types and enables expressive, readable code.

Common Operators and Their Dunder Methods

  • + → __add__, += → __iadd__
  • - → __sub__, * → __mul__
  • / → __truediv__, // → __floordiv__
  • == → __eq__, != → __ne__
  • < → __lt__, <= → __le__, > → __gt__
  • len() → __len__, abs() → __abs__
  • in → __contains__, [] → __getitem__

Reflected Operators

When a + b is evaluated, Python tries a.__add__(b) first. If that returns NotImplemented, it tries b.__radd__(a) (reflected/reverse add). Implement __radd__ when your class might appear on the right side of an operator.

Common Pitfall

Operators should return new objects, not modify self. Use __iadd__ (+=) for in-place modification. Also, __eq__ should be consistent with __hash__ if objects are used in sets or as dict keys.

Use Cases

Mathematical objects: vectors, matrices, complex numbers, polynomials

Financial calculations: Money with currency validation and arithmetic

Date/time intervals: adding/subtracting durations

Collections with custom merge/intersection behavior

Game coordinates with distance and movement operations

Common Mistakes

Modifying self in __add__ instead of returning a new object (use __iadd__ for +=)

Defining __eq__ without __hash__ — makes objects unhashable

Not handling incompatible types (return NotImplemented instead of raising TypeError)

Forgetting reflected operators (__radd__, __rmul__) for reverse operations

Overloading operators in ways that are confusing or unexpected for users