- __init__() function
- Aliases
- and operator
- argparse
- Arrays
- Booleans
- Break statement
- Bytes
- Classes
- Closure
- Code blocks
- Comments
- Conditional statements
- Console
- Context manager
- Data class
- Data structures
- Data types
- Data visualization
- datetime module
- Decorator
- Dictionaries
- Dictionary comprehension
- Django
- Docstrings
- Encapsulation
- enum
- enumerate() function
- Equality operator
- Error handling
- Exception handling
- False
- File handling
- Filter()
- Flask framework
- Floats
- Floor division
- For loops
- Formatted strings
- Functions
- Generator
- Globals()
- Greater than operator
- Greater than or equal to operator
- If statement
- in operator
- Indices
- Inequality operator
- Inheritance
- Integers
- Iterator
- Lambda function
- len() Function
- Less than operator
- Less than or equal to operator
- List append() method
- List comprehension
- List count()
- List insert() method
- List pop() method
- List reverse() method
- List sort() method
- Lists
- Logging
- map() function
- Match statement
- Math module
- Merge sort
- Min()
- Modules
- Modulo operator
- Multiline comment
- Multiprocessing
- Multithreading
- None
- not operator
- NumPy library
- OOP
- Optional arguments
- or operator
- Override method
- Pandas library
- Parameters
- pathlib module
- Pickle
- Polymorphism
- print() function
- Property()
- Protocol
- Random module
- range() function
- Raw strings
- Recursion
- Reduce()
- Regular expressions
- requests Library
- return statement
- round() function
- Script
- Set comprehension
- Sets
- SQLite
- String decode()
- String find()
- String join() method
- String replace() method
- String split() method
- String strip()
- Strings
- Ternary operator
- time.sleep() function
- True
- try...except statement
- Tuples
- Type casting
- Variables
- Virtual environment
- What is Python?
- While loops
- yield
- Zip function
PYTHON
Python Polymorphism: Syntax, Usage, and Examples
Python polymorphism lets you use the same method name or operator in different ways depending on the context. It’s a key principle of object-oriented programming (OOP) that helps you write cleaner, more flexible code.
Polymorphism is one of the concepts that makes your code feel less “copy-paste” and more like building with LEGO.
Learn Python on Mimo
How to Use Python Polymorphism
Polymorphism in Python appears in two main forms:
- Duck typing: Python's dynamic typing allows different types to implement the same method in their own way.
- Method overriding: Subclasses override a method from their parent class to provide specialized behavior.
Here's a simple example of duck typing:
Python
class Dog:
def speak(self):
return "Woof!"
class Cat:
def speak(self):
return "Meow"
def make_sound(animal):
print(animal.speak())
make_sound(Dog()) # Output: Woof!
make_sound(Cat()) # Output: Meow
The make_sound() function doesn't care what type animal is. It only cares that it has a speak() method. That’s Python polymorphism at work.
When to Use Polymorphism in Python
1. Generalizing Code for Reusability
Instead of writing separate logic for each type, you can write generic code that works with any object that implements the expected behavior. This cuts down on repetition and keeps your code DRY (Don’t Repeat Yourself).
If you have multiple classes that perform an action differently, polymorphism Python supports lets you interact with them through a single interface.
This usually leads to more maintainable code over time.
2. Enhancing Code Flexibility
Polymorphism in Python allows you to plug in new behaviors without changing existing code. You can introduce new classes that conform to an existing interface, and everything continues to work as before.
This is handy when expanding a project or working in teams where responsibilities are divided between developers.
3. Building on Inheritance
When used with inheritance, polymorphism lets child classes override methods from parent classes to customize behavior. This keeps the parent logic clean and gives subclasses the flexibility to do what they need. That parent is often called a superclass.
Examples of Polymorphism in Python
Let’s explore a few everyday examples of how Python polymorphism works.
1. Built-in Functions Acting Differently
Some Python built-ins are inherently polymorphic. For example, the len() function works on many different data types:
Python
print(len("Python")) # Output: 6
print(len([1, 2, 3])) # Output: 3
print(len({"a": 1, "b": 2})) # Output: 2
Although you’re using the same function, it behaves differently depending on the object passed in. That's polymorphism in Python based on object type.
2. Polymorphism Through Class Inheritance
Python
class Shape:
def area(self):
return 0
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side * self.side
shapes = [Circle(3), Square(4)]
for shape in shapes:
print(shape.area())
# Output:
# 28.26
# 16
Even though Circle and Square are different classes, both override the area() method, and we can treat them uniformly in a loop.
In this case, we’re using for loops to run the same code on each object during each iteration.
3. Operator Overloading
Python allows polymorphism with operators too. For instance, the + operator works across types:
Python
print(2 + 3) # Output: 5 (int addition)
print("Hi " + "there") # Output: Hi there (string concatenation)
print([1, 2] + [3]) # Output: [1, 2, 3] (list concatenation)
That last one shows the same operator working with a tuple, which makes code feel consistent once you get used to it.
This kind of polymorphism makes code more intuitive and expressive.
Learn More About Polymorphism in Python
What Is Polymorphism in Python Exactly?
In basic terms, polymorphism means “many forms.” In Python, it refers to objects of different types responding to the same method or operator call in ways appropriate to their type.
This doesn't require complex design patterns or special syntax. Thanks to Python’s dynamic nature, as long as an object implements a method, it can be used interchangeably.
This philosophy is often summed up with the phrase “If it walks like a duck and quacks like a duck, it’s a duck.” That’s the spirit of Python’s approach to polymorphism.
Implementing Polymorphism with Abstract Base Classes
Python offers tools for more formal polymorphism, like the abc module. Abstract base classes (ABCs) let you define a common interface that subclasses must implement.
Python
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof"
class Cat(Animal):
def speak(self):
return "Meow"
If a subclass doesn’t implement the speak() method, trying to create an instance will raise an error. This is helpful when building frameworks or enforcing consistency across large codebases.
Polymorphism and Interfaces
Python doesn't have a built-in interface keyword like some languages do. Instead, it relies on protocols — sets of methods that objects are expected to have.
Here’s a common example using file-like objects:
Python
def write_data(file_obj):
file_obj.write("Hello, world!")
with open("output.txt", "w") as f:
write_data(f)
As long as file_obj has a write() method, it works. That could be a real file, a mock object in a test, or something like io.StringIO.
This pattern is common in libraries that work with user-provided objects. It’s a subtle but powerful example of polymorphism Python encourages through convention rather than strict typing.
Custom Operator Overloading in User-Defined Classes
You can use special methods like __add__() or __eq__() to define how your custom class behaves with standard operators.
Python
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __str__(self):
return f"({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2) # Output: (4, 6)
This is operator polymorphism, letting objects of your class behave intuitively with built-in symbols.
Function Polymorphism via Default and Variable Arguments
Python doesn't support function overloading like Java or C++, but you can achieve flexible behavior using default arguments or *args and **args.
Python
def greet(name=None):
if name:
print(f"Hello, {name}")
else:
print("Hello, stranger")
greet("Ravi") # Output: Hello, Ravi
greet() # Output: Hello, stranger
While this isn't polymorphism in the classical sense, it achieves a similar result — one function name, different behaviors.
Polymorphism in Python and Unit Testing
Polymorphism makes unit testing easier. Since you can substitute different classes with the same interface, you can inject mock versions during testing.
Python
class FakeFile:
def write(self, text):
print(f"Mock write: {text}")
write_data(FakeFile()) # Output: Mock write: Hello, world!
This keeps tests fast, clean, and independent from external resources like the file system or network.
Polymorphism in Practice
Polymorphism becomes extra useful once your Python classes start interacting with real application data.
For example, you might load objects from JSON and then call the same method on all of them, even if they represent different things:
User.save()Product.save()Invoice.save()
Each class can handle saving differently, but your code still calls save() the same way. This is a very real-world use of polymorphism.
You’ll also see polymorphism show up in places like machine learning, where a “model” might expose the same predict() method even when the implementation differs under the hood.
Polymorphism also pairs nicely with encapsulation because your code doesn’t need to know how something works internally, just what methods it exposes.
If you want to create alternate constructors cleanly, class methods like from_dict() or from_json() are a common pattern:
Python
classUser:
def__init__(self, name):
self.name = name
@classmethod
deffrom_dict(cls, data):
return cls(data["name"])
And if you want to add behavior (like logging or timing) without rewriting your logic, decorators can wrap those methods while keeping the calling code the same.
Also, polymorphism in Python happens at runtime, which is different from languages where a compiler can catch more type issues before the program runs.
Python polymorphism allows you to use the same method or operator on different types of objects. By focusing on behavior rather than strict types, polymorphism in Python makes your code easier to read, extend, and reuse.
You’ll see it in action all over the language — from built-in functions like len() to your own class hierarchies. With duck typing, method overriding, abstract base classes, and operator overloading, Python polymorphism is both powerful and practical.
Join 35M+ people learning for free on Mimo
4.8 out of 5 across 1M+ reviews
Check us out on Apple AppStore, Google Play Store, and Trustpilot