Method overloading in Python

Method overloading is sometimes referred to as “polymorphism” and means that a method can have two or more different meanings at different places in a program’s execution. It should not be confused with method overriding which usually comes with object oriented programming and inherited classes.In method overloading you have two different definitions of a method with the same name but different signatures (e.g., they take different numbers of arguments or different types of arguments or both). In method overriding you typically have two different definitions of a method, one with the parent class and one with a child class but they usually have the same signatures.Here is a simple example with a Restaurant class:

class Restaurant:
def __init__(self,name,address):
self.name = name
self.address = address
def fullname(self):
return (self.name + " located at " + self.address)

As you can see from the code, the Restaurant class has two attributes which are name and address. The method “fullname” returns a string containing both attributes. We can now define a Restaurant and print its fullname by the following code:

r = Restaurant("Corner Cafe","123 Main Street")
print(r.fullname())

The output will be:

Corner Cafe located at 123 Main Street

Now let us overload the method. We will create another method with the same name inside the same class.

class Restaurant:
def __init__(self,name,address):
self.name = name
self.address = address
def fullname(self):
return (self.name + " located at " + self.address)
def fullname(self):
return (self.name + ", " + self.address)

Now if we run our code again:

r = Restaurant("Corner Cafe","123 Main Street")
print(r.fullname())

We will get the output:

Corner Cafe, 123 Main Street

What has happened here? Note that the fullname() method now invokes the new definition and it is as if the old definition does not exist at all! Furthermore we haven’t explored the full notion of overloading because the two methods have the same signature.Let us complicate matters by updating the signature of the second fullname() method.

class Restaurant:
def __init__(self,name,address):
self.name = name
self.address = address
def fullname(self):
return (self.name + " located at " + self.address)
def fullname(self,middle):
return (self.name + middle + self.address)

Now the same code as before gives the output:

Traceback (most recent call last):
File "main.py", line 15, in <module>
print(r.fullname())
TypeError: fullname() missing 1 required positional argument: 'middle'

We get an error indicating that Python is expecting the middle argument in the invocation we are making to the fullname() method, even though there exists another fullname() method that doesn’t require that argument. In other words, Python is really not doing any method overloading! When you give multiple method definitions, Python simply takes the most recent definition, forgets any previous definitions, and expects you to follow the invocation pattern of the most recent definition.If we update our driver code:

r = Restaurant("Corner Cafe","123 Main Street")
print(r.fullname(" used to be at "))

We get no errors and the output:

Corner Cafe used to be at 123 Main Street

So can we implement method overloading at all in Python? It turns out there is a sly way to do it using a generic argument to your method that you then unpack inside the definition of your method. Here’s how that works:

class Restaurant:
def __init__(self,name,address):
self.name = name
self.address = address
def fullname(self, *args):
filler_phrase = ""
for x in args:
filler_phrase = filler_phrase + x
return (self.name + filler_phrase + self.address)

The above code is essentially helping you to view the method as having multiple definitions as follows:

Note that we have removed the earlier definitions of the fullname() method and now we have a method that takes a generic second argument which is then unpacked inside a for loop and then concatenated into the output.Here is some driver code:

r = Restaurant("Corner Cafe","123 Main Street")
print(r.fullname(" used to be at "))
print(r.fullname())
print(r.fullname(", the really cool place", " located at ",))

Note that we have overloaded the fullname() method in all our invocations, once with one argument, once with no arguments, and finally with two arguments. The output is:

Corner Cafe used to be at 123 Main Street
Corner Cafe123 Main Street
Corner Cafe, the really cool place located at 123 Main Street

There is another way to do method overloading using Python decorators but that is beyond the scope of this post. Stay tuned for a future blogpost!If you are interested to learn more about Python object oriented programming features checkout our post about private methods in Python.Interested in more things Python? See our blogpost on Python’s enumerate() capability. Also if you like Python+math content, see our blogpost on Magic Squares. Finally, master the Python print function!Want to learn Python with us? Sign up for 1:1 or small group classes.

Originally published at kodeclik.com

--

--

Kodeclik - Coding for Kids and Teens

Kodeclik is an online Coding and Math academy for kids and teens.