Understanding Polymorphism in Python (With Examples)
What is polymorphism in Python?
Polymorphism in Python refers to the ability of different objects to respond to the same method or function call in ways specific to their individual types. The term comes from Greek words “poly” (many) and “morphos” (forms), literally meaning “many forms.” Polymorphism is a core concept in object-oriented programming (OOP) that allows programmers to use a single interface with different underlying forms.
In Python, polymorphism enables you to write more flexible and reusable code by allowing objects of different classes to be treated as objects of a common superclass. This fundamental OOP principle makes your code more modular, extensible, and easier to maintain.
Let’s explore how polymorphism works in Python with a simple example:
class Bird:def sound(self):return "Tweet"class Dog:def sound(self):return "Bark"def make_sound(animal):print(animal.sound())# Create objectsbird = Bird()dog = Dog()# Same function call, different behaviorsmake_sound(bird) # Output: Tweetmake_sound(dog) # Output: Bark
In this example, both Bird
and Dog
classes have a method called sound()
, but each implementation returns a different result. The make_sound()
function accepts any object that has a sound()
method, demonstrating polymorphism in action.
Learn Java: Inheritance and Polymorphism
Learn how to go further with classes by using inheritance and polymorphism.Try it for freeTypes of polymorphism in Python
Python supports several types of polymorphism. Understanding each type will help you leverage polymorphism effectively in your code.
1. Duck typing
Duck typing is a concept related to dynamic typing where the type or class of an object is less important than the methods it defines. The name comes from the saying: “If it walks like a duck and quacks like a duck, then it probably is a duck.”
class Duck:def swim(self):return "Duck swimming"def fly(self):return "Duck flying"class Airplane:def fly(self):return "Airplane flying"def fly_test(entity):print(entity.fly())# Create objectsduck = Duck()airplane = Airplane()# Same function works with different objectsfly_test(duck) # Output: Duck flyingfly_test(airplane) # Output: Airplane flying
In this example, the fly_test()
function works with any object that has a fly()
method, regardless of its type. This is a typical example of duck typing.
2. Method overriding
Method overriding occurs when a subclass provides a specific implementation of a method that is already defined in its parent class. This is one of the most common forms of polymorphism in Python.
class Animal:def speak(self):return "Animal makes a sound"class Cat(Animal):def speak(self):return "Meow"class Cow(Animal):def speak(self):return "Moo"# Create objectsanimal = Animal()cat = Cat()cow = Cow()# Same method name, different behaviorsprint(animal.speak()) # Output: Animal makes a soundprint(cat.speak()) # Output: Meowprint(cow.speak()) # Output: Moo
In this example, both Cat
and Cow
classes override the speak()
method of their parent class Animal
.
3. Operator overloading
Operator overloading is a feature in Python that allows the same operator to have different meanings according to the context. For instance, the +
operator performs arithmetic addition on numbers but concatenation on strings.
class Point:def __init__(self, x, y):self.x = xself.y = ydef __add__(self, other):return Point(self.x + other.x, self.y + other.y)def __str__(self):return f"Point({self.x}, {self.y})"# Create Point objectsp1 = Point(1, 2)p2 = Point(3, 4)# Using the + operator on Point objectsp3 = p1 + p2print(p3) # Output: Point(4, 6)
In this example, we’ve overloaded the +
operator for the Point
class by implementing the __add__
special method.
4. Function and method overloading
Unlike some other OOP languages, Python doesn’t support traditional function or method overloading, where multiple methods with the same name but different parameters are defined. However, Python achieves similar functionality through default parameters and variable-length arguments.
def calculate_area(length, width=None):if width is None:return length * lengthreturn length * width# Using the function with different argumentsprint(calculate_area(5)) # Output: 25 (square)print(calculate_area(4, 6)) # Output: 24 (rectangle)
This example shows how a single function can handle different types of inputs, demonstrating polymorphic behavior.
Examples of polymorphism in Python
Let’s look at some more practical examples of polymorphism in Python to better understand how it works in real-world scenarios.
Example 1: Polymorphism with class methods
class Shape:def area(self):passdef perimeter(self):passclass Rectangle(Shape):def __init__(self, length, width):self.length = lengthself.width = widthdef area(self):return self.length * self.widthdef perimeter(self):return 2 * (self.length + self.width)class Circle(Shape):def __init__(self, radius):self.radius = radiusdef area(self):return 3.14 * self.radius * self.radiusdef perimeter(self):return 2 * 3.14 * self.radius# Create shape objectsrectangle = Rectangle(5, 4)circle = Circle(3)# Process different shapes using the same methodsshapes = [rectangle, circle]for shape in shapes:print(f"Area: {shape.area()}")print(f"Perimeter: {shape.perimeter()}")
In this example, both Rectangle
and Circle
inherit from Shape
and override its methods. We can process different shapes with the same code, demonstrating polymorphism.
Example 2: Polymorphism with built-in functions
Python’s built-in functions like len()
and str()
also demonstrate polymorphism. They work with different types of objects:
# The len() function with different data typesprint(len("Hello")) # Output: 5print(len([1, 2, 3])) # Output: 3print(len({"name": "John", "age": 30})) # Output: 2# The str() function with different data typesprint(str(123)) # Output: "123"print(str([1, 2, 3])) # Output: "[1, 2, 3]"print(str({"a": 1})) # Output: "{'a': 1}"
Here, len()
and str()
behave differently based on the type of object they’re called with, demonstrating polymorphic behavior.
Why use polymorphism in Python
Polymorphism offers several benefits that make it a valuable tool in Python programming:
Code Reusability: Polymorphism allows you to reuse code by defining methods in a base class that subclasses can override according to their specific needs.
Flexibility: It provides flexibility to use objects of different types through a common interface, making your code more adaptable to changes.
Abstraction: Polymorphism helps in hiding the complex implementation details while exposing a simple interface to the users of your code.
Maintainability: By promoting code organization and reusability, polymorphism makes your code easier to maintain and extend.
Cleaner Code: It reduces conditional statements and type checks, resulting in cleaner and more readable code.
Practical applications of polymorphism
Polymorphism isn’t just a theoretical concept; it has numerous practical applications in real-world Python programming:
Application 1: GUI programming
In graphical user interface (GUI) programming, different UI elements (buttons, text boxes, etc.) may respond differently to the same events (clicks, keypresses):
class Button:def click(self):return "Button clicked"class Checkbox:def click(self):return "Checkbox toggled"def handle_click(ui_element):print(ui_element.click())# Create UI elementsbutton = Button()checkbox = Checkbox()# Handle clicks on different elementshandle_click(button) # Output: Button clickedhandle_click(checkbox) # Output: Checkbox toggled
Application 2: database interfaces
Different database systems can be accessed through a common interface using polymorphism:
class Database:def connect(self):passdef execute_query(self, query):passclass MySQLDatabase(Database):def connect(self):return "Connected to MySQL"def execute_query(self, query):return f"Executing in MySQL: {query}"class PostgreSQLDatabase(Database):def connect(self):return "Connected to PostgreSQL"def execute_query(self, query):return f"Executing in PostgreSQL: {query}"def run_query(database, query):print(database.connect())print(database.execute_query(query))# Create database objectsmysql = MySQLDatabase()postgres = PostgreSQLDatabase()# Run the same query on different databasesrun_query(mysql, "SELECT * FROM users")run_query(postgres, "SELECT * FROM users")
Application 3: file handling
Polymorphism can be used to handle different file types with a uniform interface:
class FileHandler:def open(self, filename):passdef process(self, data):passclass TextFileHandler(FileHandler):def open(self, filename):return f"Opening text file: {filename}"def process(self, data):return f"Processing text data: {data}"class ImageFileHandler(FileHandler):def open(self, filename):return f"Opening image file: {filename}"def process(self, data):return f"Processing image data: {data}"def handle_file(handler, filename, data):print(handler.open(filename))print(handler.process(data))# Create file handlerstext_handler = TextFileHandler()image_handler = ImageFileHandler()# Handle different file typeshandle_file(text_handler, "document.txt", "Hello World")handle_file(image_handler, "photo.jpg", "Binary data")
Conclusion
Polymorphism in Python is a powerful concept that allows for more flexible, reusable, and maintainable code. By understanding and applying the different types of polymorphism — duck typing, method overriding, operator overloading, and function overloading — you can write more elegant and efficient Python programs.
To deepen your understanding of object-oriented programming concepts like polymorphism, check out Codecademy’s Learn Python 3 course, which covers these topics in depth with interactive exercises.
Frequently Asked Questions
1. What is the difference between polymorphism and inheritance in Python?
While both are important OOP concepts, they serve different purposes. Inheritance is a mechanism where a class inherits attributes and methods from another class. It promotes code reuse and establishes a parent-child relationship between classes. Polymorphism, on the other hand, is the ability to use a common interface for different types of objects. Polymorphism often works with inheritance but can also exist independently (as in duck typing).
2. What is the role of the isinstance()
function in polymorphism?
The isinstance()
function can be used to check if an object is an instance of a specific class or its subclasses. While it’s sometimes useful, relying too heavily on isinstance()
checks can defeat the purpose of polymorphism, which aims to treat objects based on their behavior rather than their types. Duck typing is often a more Pythonic approach.
3. Can I use polymorphism with Python’s built-in data types?
Yes, Python’s built-in types like lists, dictionaries, and strings already exhibit polymorphic behavior with operations like iteration, indexing, and methods like append()
, update()
, etc. You can also extend built-in types to add custom polymorphic behavior.
4. Is polymorphism only useful in large applications?
While polymorphism shows its full potential in larger applications, it can be beneficial even in smaller projects. By promoting cleaner, more organized code, polymorphism makes your code more maintainable and easier to extend, regardless of the project size.
'The Codecademy Team, composed of experienced educators and tech experts, is dedicated to making tech skills accessible to all. We empower learners worldwide with expert-reviewed content that develops and enhances the technical skills needed to advance and succeed in their careers.'
Meet the full teamRelated articles
- Article
Python Inheritance Explained: Types and Use Cases
Learn what Python inheritance is and how it enables code reuse. Explore different types of inheritance, such as single, multiple, and hybrid. Understand the `super()` function and real-world applications of inheritance in Python. - Article
Python Glossary
Programming reference for Python - Article
How to use Generative AI for Unit Testing
Learn how to use ChatGPT and generative AI for unit testing in Python code. This guide covers basic and edge case testing, ensuring your code performs reliably.
Learn more on Codecademy
- Free course
Learn Java: Inheritance and Polymorphism
Learn how to go further with classes by using inheritance and polymorphism.Beginner Friendly2 hours - Course
Learn Object-Oriented Programming (OOP) with C++
In this course, we will discuss the four basic principles of object-oriented programming and see how we can implement and use them in C++.With CertificateIntermediate10 hours - Free course
Learn Java: Classes, Methods, Inheritance, and Polymorphism
Take a deeper look into Java classes and methods and learn the basics of encapsulation.Beginner Friendly4 hours