Operator overloading in Python; or, how to lose friends and annoy people

Today we’ll do some operator overloading, or change the behavior of some infix operators (+ and *) for our own handmade classes.

There are legitimate reasons for doing so: if adding a behavior for + makes sense for your class, you can improve the readability of your code and make your classes easier to use. Of course, it’s also a power that can be abused (the creator of Java did not include operator overloading in that language because he said he saw it abused in C++, which is probably a reflection of the character of C++ programmers).

For example, let’s look at the behavior of + for built-in tuples and lists.

x_list = [2,3,4]
y_list = [5,6,7]
add_list = x_list + y_list
print(add_list)

Using + on lists concatenates them! This is a problem if we were hoping to add the elements of the lists together.

But, what if I want + to do vector addition and * vector multiplication?!

# we could use numpy, of course
import numpy as np
 x = np.array((2,3,4))
 y = np.array([5,6,7])
 add_np_array = x+y
 print(add_np_array)
 mult_np_array = x*y
 print(mult_np_array)

But using numpy isn’t so much fun, so let’s build our own vector

We’ll build our own tuple class and call it my_vector. We’ll overload + to make it do vector addition.

import numpy as np
import itertools

class my_tuple:
    '''Create my own tuple class that overloads + and * so I can get vector addition 
        and multiplication. 
        
        It may also overload some operator in some unexpected way, but I won't tell you how, muahahaha'''
    
    def __init__(self , data):
        self.data= tuple(data)
    
    def __iter__(self):
        return iter(self.data)
    
    def __repr__(self):
        return str(self.data)
      
    def __add__(self,other):
        combo = itertools.zip_longest(self,other,fillvalue=0.0)
        return my_tuple(a+b for a,b in combo)

What happens if you run the following code now using our new class?

tup = my_tuple((2,3,4,25))
tup2 = my_tuple((5,6,7))
add_my_tup = tup + tup2
add_my_tup

We should get the following:

(10, 18, 28, 0)

Wow, looks like our overloading worked! You can also overload other operators, including > and <. You’ll first need to know the name of the dunder method in Python (that is, __add__ for addition or __lt__ for less than), but applying it is straightforward as we saw above!

Categories:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s