Operator Overloading
Master operator overloading to make your classes behave like built-in types. Learn the techniques used by NumPy, PyTorch, Pandas, and SQLAlchemy to create intuitive, powerful APIs through custom operator behaviors.
Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
🔥 Operator Overloading & Custom Behaviours
Operator overloading lets your classes behave like built-in types:
- ✔ Dictionaries
- ✔ Comparisons
- ✔ Arithmetic
- NumPy → vector arithmetic
- PyTorch → tensor operations
- SQLAlchemy → query expressions
- Pandas → Series/DataFrame math
- Pathlib → path addition
- Datetime → duration arithmetic
If you want to build professional-grade classes, operator overloading is mandatory.
⚙️ 1. Why Operator Overloading Exists
Python allows classes to define behavior for:
You override these by implementing "magic methods" such as:
- __add__ , __sub__ , __mul__ , __truediv__
- __eq__ , __lt__
- __getitem__ , __setitem__
- __contains__ , __len__ , __bool__ , __call__
These make your objects feel native and intuitive.
🔢 2. Overloading Arithmetic Operators
Let's build a simple 2D vector class with all arithmetic operators:
🧠 3. Overloading String & Representation Functions
Two methods control how your objects appear in logs, REPLs, and print statements:
🧩 4. Comparison Operators
To support sorting, filtering, searching, or ordering, implement:
📦 5. Overloading Indexing & Slicing
🔄 6-7. Membership & Iteration
🔥 8-9. Boolean & Call Behavior
⚡ 10-11. Reverse & Augmented Operators
🎯 12-13. Rich Container & Matrix Indexing
🌀 14-16. Bitwise & Context Operators
👑 17-19. DSL Building with Operators
Massive libraries rely on operator overloads to create readable "fake languages":
- SQLAlchemy: User.age > 18
- PyTorch: x = tensor * 3 + tensor2
- Pandas: df["col"] + df["other"]
- Pathlib: path = Path("home") / "user"
🧩 20-22. Attribute Access & Delegation
🔥 23-24. Complete Mathematical System
🧵 25-27. Immutable vs Mutable Design
⚡ 28-30. Computation Graphs & Best Practices
🎯 Summary — You Now Understand the Full Python Operator Model
- ✔ Operator dispatching
- ✔ Delegation
- ✔ Emulating built-ins
- ✔ Full numerical operator suite
- ✔ Boolean overloading
- ✔ Callable objects
- ✔ Immutable vs mutable design
- ✔ DSL construction
- ✔ Computation graph building
- ✔ Best practices for errors
- ✔ Weakref integration
This puts you at a framework engineer level (the people who build NumPy/Pandas/PyTorch, not just use them).
📋 Quick Reference — Operator Overloading
Method
Operator
__add__(self, other)
a + b
__eq__(self, other)
a == b
__lt__(self, other)
a < b (enables sorting)
__mul__(self, other)
a * b
@functools.total_ordering
Auto-fill comparison methods
Your classes can now support arithmetic, comparisons, and other operators — making your APIs as intuitive as built-in Python types.
Up next: Mixins — compose reusable behaviour across multiple classes without deep inheritance chains.
Practice quiz
Which magic method implements the + operator?
- __plus__
- __sum__
- __add__
- __concat__
Answer: __add__. Defining __add__(self, other) makes a + b work on your objects.
Which magic method enables == comparisons?
- __eq__
- __equals__
- __cmp__
- __is__
Answer: __eq__. __eq__ controls the == operator.
Implementing __lt__ on a class primarily enables what?
- Addition
- Indexing
- Iteration
- Sorting and < comparisons
Answer: Sorting and < comparisons. __lt__ defines < and lets Python sort instances with sorted().
When is __rmul__ called?
- Never
- When the left operand (e.g. an int) doesn't know how to multiply your object
- Only inside loops
- When you call the object
Answer: When the left operand (e.g. an int) doesn't know how to multiply your object. __rmul__ handles the reflected case like 3 * v where the left operand can't handle it.
Which method makes an object respond to the len() built-in?
- __len__
- __size__
- __count__
- __length__
Answer: __len__. __len__ defines what len(obj) returns.
Which method makes an object callable like a function, obj(x)?
- __invoke__
- __run__
- __call__
- __exec__
Answer: __call__. __call__ lets an instance be called like obj(x).
Which method controls the [] indexing operator, obj[key]?
- __index__
- __getitem__
- __getattr__
- __get__
Answer: __getitem__. __getitem__ handles obj[key] indexing and slicing.
In the lesson, what does the Path class's __truediv__ let you write?
- Path('a') + 'b'
- Path('a') * 2
- Path('a') - 'b'
- Path('home') / 'user'
Answer: Path('home') / 'user'. __truediv__ overloads /, so Path('home') / 'user' builds a path like Pathlib.
What should an arithmetic operator return for an unsupported operand type?
- None
- NotImplemented
- Raise immediately
- False
Answer: NotImplemented. Returning NotImplemented lets Python try the reflected operator before raising TypeError.
Which method makes a permission flags class support the | operator (READ | WRITE)?
- __bitor__
- __pipe__
- __or__
- __union__
Answer: __or__. __or__ overloads the bitwise | operator.