What Is Operator Overloading in Python?

An image of sparks flying with the title of the article overlayed

Python has a cool feature that allows you to overload the operators. Let’s talk about what that means and how you might use it!

Table of Contents

Concept Overview

As a concept in computer science, overloading typically refers to the ability to have multiple behaviors for the same syntax. For example, you may be familiar with method overloading, which is when multiple methods have the same name but different sets of parameters.

Extending the concept of overloading to operators introduces the ability to have multiple behaviors for the same operator. Not all programming languages support operator overloading, but Python is one of them. That’s why you will sometimes see familiar operators used in strange contexts.

To illustrate this point, consider the addition operator (i.e., +). The addition operator can be used to add numbers together:

5 + 7 # evaluates to 12

Of course, the addition operator can also be used to concatenate strings:

"Yusuke" + "Urameshi" # evaluates to "YusukeUrameshi"

Or, you might use the addition operator to combine lists:

[1, 2] + [3, 4] # evaluates to [1, 2, 3, 4]

In fact, there are probably a dozen native uses for the addition operator. That’s the power of operator overloading! In the remainder of this article, we’ll look at some questions you might have about operator overloading.

How Do You Overload an Operator?

Operators are defined at the class level. In other words, you can overload an operator for any custom type you would like. As a simple example, we might imagine making a 2D point class as follows:

class Point2D:
  def __init__(self, x: int, y: int):
    self.x = x
    self.y = y

And just so we can see how it works, we should also implement the repr() method:

class Point2D:
  def __init__(self, x: int, y: int):
    self.x = x
    self.y = y
  def __repr__(self):
    return f"({self.x}, {self.y})"

Now, when we create a point in a REPL like IDLE, we can see the point in typical notation:

>>> Point2D(3, 4)
(3, 4)

Next, we can overload the addition operator by implementing the add() method:

class Point2D:
  def __init__(self, x: int, y: int):
    self.x = x
    self.y = y
  def __repr__(self):
    return f"({self.x}, {self.y})"
  def __add__(self, other):
    return Point2D(self.x + other.x, self.y + other.y)

Now, when two points are added together, we will get a new point with their components summed together:

>>> Point2D(3, 4) + Point2D(1, 2)
(4, 6)

Note that I don’t think it’s proper math to be able to add two points together. That’s more of a vector thing, but you get the idea!

Isn’t Operator Overloading Bad Practice?

You may have heard that operator overloading is bad practice. After all, some programming languages like Java prohibit it. In my experience, it’s a delicate balance. It is definitely possible to overload operators in a way that makes code harder to read (e.g., overloading obscure operators). It’s also possible to overload operators in a way that purposely confuses the reader (e.g., overloading subtraction to do addition).

With that said, in programming languages like Java where operator overloading is not possible, you can really feel it. For example, you might have used the Comparator interface at some point in Java. It’s practically required to know how to use a Comparator in Java because so much of the standard library relies on it for sorting and ordering elements. As a result, you’ve certainly come across the following syntax:

if (x.compareTo(y) > 0) { ... }

No matter how many times I see this syntax, I have to remind myself what it means. If Java simply allowed us to overload the less-than and greater-than operators, we could have syntax like the following:

if (x > y) { ... }

Fortunately, I am not the only one irritated by this limitation. In fact, the developers of Kotlin have as wellOpens in a new tab., and any attempts to use the typical Comparator syntax will result in some linter warnings.

With that said, I do think there’s an issue with languages that have too many operators (e.g., Perl). Explicit is generally going to be better than implicit, so flooding a language with symbols is not ideal. That’s partially why folks got so fired up about the walrus operator back in Python 3.8.

Overloading Your Brain

Personally, operator overloading is not a feature I use very often. However, in the few case I have, it’s made my code a lot easier to use. I would recommend at least toying with the feature because it’s not just available for the math or relational operators. You can also overload the indexing syntax (i.e., x[i]).

At any rate, let’s call it a day! Hopefully you enjoyed this one. If not, why not try one of the following articles:

Likewise, you might enjoy some of these resources (#ad):

Alternatively, you might enjoy taking your support a step further by checking out my list of ways to grow the site. If not, no sweat! Take care.

The Python Concept Map (13 Articles)—Series Navigation

An activity I regularly do with my students is a concept map. Typically, we do it at the start and end of each semester to get an idea of how well our understanding of the material as matured over time. Naturally, I had the idea to extend this concept into its own series, just to see how deeply I can explore my own knowledge of Python. It should be a lot of fun, and I hope you enjoy it!

Jeremy Grifski

Jeremy grew up in a small town where he enjoyed playing soccer and video games, practicing taekwondo, and trading Pokémon cards. Once out of the nest, he pursued a Bachelors in Computer Engineering with a minor in Game Design. After college, he spent about two years writing software for a major engineering company. Then, he earned a master's in Computer Science and Engineering. Today, he pursues a PhD in Engineering Education in order to ultimately land a teaching gig. In his spare time, Jeremy enjoys spending time with his wife and kid, playing Overwatch 2, Lethal Company, and Baldur's Gate 3, reading manga, watching Penguins hockey, and traveling the world.

Recent Code Posts