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 that helps you write cleaner, more flexible code.


How to Use Python Polymorphism

Polymorphism in Python appears in two main forms:

  1. Duck typing: Python's dynamic typing allows different types to implement the same method in their own way.
  2. Method overriding: Subclasses override a method from their parent class to provide specialized behavior.

Here's a simple example of duck typing:

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.

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.


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:

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

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.

3. Operator Overloading

Python allows polymorphism with operators too. For instance, the + operator works across types:

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)

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.

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:

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.

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.

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.

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.


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.

Learn to Code in Python for Free
Start learning now
button icon
To advance beyond this tutorial and learn Python by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

You can code, too.

© 2025 Mimo GmbH

Reach your coding goals faster