What is Polymorphism in Python?
Tags: python, programming, tutorial
Published: 2022-06-15 20:42:17

Python is one of the most popular programming languages due to its **versatility** and its **user-friendly syntax**. Like other languages that accommodate object-oriented programming (OOP), Python is **polymorphic**. This means that a single operator, function, or class method in Python can have multiple uses. These various uses might be challenging to learn, but they ultimately make Python a more efficient language. 

Today, we’ll discuss polymorphism and how it works in Python.

**We'll cover the following topics:**
* [What is polymorphism?](#polymorphism)
* [Examples of polymorphism in Python](#examples)
* [Python polymorphism tutorial](#tutorial)
* [Wrapping up and next steps](#nextsteps)

<a name="polymorphism"></a>

## What is polymorphism?

Polymorphism is the principle that one kind of thing can take a variety of forms. In the context of programming, this means that a **single entity in a programming language can behave in multiple ways** depending on the context. It’s similar to how a word like “express” can act as a verb in one sentence, a noun in another sentence, and an adjective in a third sentence. The sequence of letters on the page doesn’t change, but the meaning they add to the sentence is fundamentally different in each case. Likewise, in polymorphic programming languages, a single entity can act differently in different contexts.

<a name="examples"></a>

## Examples of polymorphism in Python

Polymorphism is a basic condition of Python, and it affects how the language works at multiple levels. Today, we’ll focus on the polymorphism of operators, functions, and class methods in Python.

### Operator Polymorphism

Operator polymorphism, or operator overloading, means that **one symbol can be used to perform multiple operations**. One of the simplest examples of this is the addition operator `+`. Python’s addition operator works differently in relation to different data types. 

For example, if the `+` operates on two integers, the result is additive, returning the **sum** of the two integers. 

```
int1 = 10
int2 = 15
print(int1 + int2)
# returns 25
```

In the example above, the `+` operator adds `10` and `15`, such that the output is `25`. 

However, if the addition operator is used on two strings,  it **concatenates** the strings. Here’s an example of how the `+` operator acts on string data types.

```
str1 = "10"
str2 = "15"
print(str1 + str2)
# returns 1015
```

In this case, the output is `1015` because the `+` operator concatenates the strings `“10”` and `“15”`. This is one example of how a single operator can perform distinct operations in **different contexts**.

### Function Polymorphism

Certain functions in Python are polymorphic as well, meaning that they can act on multiple data types and structures to yield different kinds of information. 

Python’s built-in `len()` function, for instance, can be used to return the length of an object. However, it will measure the length of the object differently **depending on the object’s data type and structure** For instance, if the object is a string, the `len()` function will return the number of characters in the string. If the object is a list, it will return the number of entries in the list. 

Here’s an example of how the `len()` function acts on strings and lists:

```
str1 = "animal"
print(len(str1))
# returns 6

list1 = ["giraffe","lion","bear","dog"]
print(len(list1))
# returns 4
```

The outputs are `6` and `4`, respectively, because the `len()` function counts the number of characters in a string and the number of entries in a list. The function operates differently depending on the nature of the data it’s acting on.

### Class and Method Polymorphism

Python’s polymorphic nature makes it easier to repurpose classes and methods. Remember that a **class is like a blueprint**, and an **object is a concrete instantiation of that blueprint**. So, a method that is part of a class will reoccur in the objects that instantiate that class. Likewise, if you generate a new class from a preexisting class, the new class will inherit the methods of the preexisting class. The new class in this scenario is called a “child class,” while the preexisting class is called the “parent class.”

Here's an example of a parent class and a child class that’s derived from it. Note that the parent class establishes the method `type`, so the child class inherits that method. The method is redefined in the child class, however, such that objects instantiated from the child class use the redefined method. This is called “**method overriding**.”

```
# Define parent class Animal
class Animal:

# Define method
    def type(self):
        print("animal")

# Define child class Dog	
class Dog (Animal):
    def type(self):
        print("dog")


# Initialize objects
obj_bear = Animal()
obj_terrier = Dog()

obj_bear.type()
# returns animal
obj_terrier.type()
# returns dog
```

The method name `type` remains the same in the child class, but it has been overridden. An object instantiated from the parent class will use the original method as it is defined in the parent class, while a method instantiated from the child class will use the overridden method. Therefore, the outputs from the program above are `animal` and `dog`, respectively.

A similar principle applies to classes that are independent of each other. For instance, imagine that you’re creating two new classes: `Lion` and `Giraffe`.

```
class Lion:
    def diet(self):
        print(“carnivore”)

class Giraffe:
    def diet(self):
        print(“herbivore”)

obj_lion=Lion()
obj_giraffe=Giraffe()

obj_lion.diet()
# returns carnivore
obj_giraffe.diet()
# returns herbivore
```

The outputs from this program are `carnivore` and `herbivore`, respectively. The two classes both use the method name `diet`, but they define those methods differently. An object instantiated from the `Lion` class will use the method as it is defined in that class. The `Giraffe` class may have a method with the same name, but objects instantiated from the `Lion` class won’t interact with it.

<a name="tutorial"></a>

## Python polymorphism tutorial

The best way to learn a new coding skill is by **actually practicing it**. Try running the code in the examples below to see polymorphism in action!
First, let’s practice operator polymorphism. We’ll use the `+` operator to add the integers `2` and `3` while concatenating the strings `“2”` and `“3”`.

```
int1 = 2
int2 = 3
print(int1+int2)

str1 = "2"
str2 = "3"
print(str1+str2)

---> 5
    23
```
Next, try using the `len()` function to measure the length of the string `“numbers”` and the list `[“1”,“2”,“3”,“4”]`.

```
str1="numbers"
print(len(str1))

list1=["1","2","3","4"]
print(len(list1))

---> 7
     4
```
Class method polymorphism is a little more complicated. In the code block below, we’ve created a parent class `Fish` and defined a class method `type`. We’ve then created a child class called `Shark` while overriding the `type` method so that objects instantiated from the `Shark` class use the overridden method.

```
class Fish:
       def type(self):
             print("fish")

class Shark(Fish):
	def type(self):
	      print("shark")

obj_goldfish=Fish()
obj_hammerhead=Shark()

obj_goldfish.type()

obj_hammerhead.type()

---> fish
     shark
```

Finally, below, we’ve created two new, independent classes: `Turtle` and `Frog`. When you instantiate an object from the `Turtle` class, the object will use the `type` method as it is defined in that class. The same will be true of objects instantiated from the `Frog` class, despite the fact that the methods have the same name.

```
class Turtle:
    def type(self):
        print("turtle")

class Frog:
    def type(self):
        print("frog")

obj_sea_turtle=Turtle()
obj_treefrog=Frog()

obj_sea_turtle.type()

obj_treefrog.type()

---> turtle
     frog
```

<a name="nextsteps"></a>

## Wrapping up and next steps

Polymorphism is an important element of object-oriented programming in Python. Polymorphism makes Python a more versatile and efficient language. It allows you to use a **single operator or function** to perform multiple tasks. It also allows you to reuse method names while redefining them for the unique purposes of different classes. 

Learning how to make use of the polymorphism of operators, functions, and class methods might be challenging, but once you’ve done so, you’ll be **a more adept programmer**. 

To learn more about using Python, consider exploring Educative’s [**Python for Programmers**](https://www.educative.io/path/python-for-programmers?eid=5082902844932096) learning path. Over the course of four modules, you’ll learn the fundamentals of Python and then gradually progress to more advanced skills. If you’re already familiar with Python and are preparing for an interview, consider the [**Ace the Python Coding Interview**](https://www.educative.io/path/ace-python-coding-interview?eid=5082902844932096) learning path. It will help you brush up on your Python skills while also giving you opportunities to practice real interview questions.

*Happy learning!*

*To get more Python content delivered right to your email inbox, check out our [Grokking Python](https://www.grokkingpython.com) newsletter on Substack!*

### Continue Learning About Python on Educative

* [Wrapping your head around neural networks in Python](https://www.educative.io/blog/neural-networks-python?eid=5082902844932096)

* [7 top Python libraries for data science and machine learning](https://www.educative.io/blog/python-libraries-for-data-science-and-machine-learning?eid=5082902844932096)

* [What can you do with Python? 5 real-world applications](https://www.educative.io/blog/what-can-python-do-5-applications?eid=5082902844932096)

### Start a discussion

What else do you want to learn about Python? Was this article helpful? Let us know in the comments below!