Python Polymorphism

Ka Kavitha V Updated 03 Oct 2026
5 min read

Polymorphism

The word polymorphism comes from Greek and means "many forms". In programming, polymorphism means that the same function or method name can behave differently depending on the object or data type it is used with.

You call one name — len(), speak(), operate() — and each type of object responds in its own appropriate way. This makes code more flexible, reusable, and easier to extend, because the calling code does not need to know exactly what kind of object it is working with.

Function Polymorphism

Many of Python's built-in functions work with different data types and automatically adapt their behavior.

Example: The len() Function

len() With a String

Returns the number of characters.

text = "Python Rocks"
print(len(text))

Expected output:

12

The space counts as a character: 6 + 1 + 5 = 12.

len() With a List

Returns the number of items.

colors = ["red", "blue", "green", "yellow"]
print(len(colors))

Expected output:

4

len() With a Dictionary

Returns the number of key–value pairs.

user_info = {
    "username": "admin",
    "role": "editor",
    "active": True
}

print(len(user_info))

Expected output:

3

The function name is the same each time, but what it measures depends on the type of object. This is function polymorphism.

Operator Polymorphism

Operators are polymorphic too. The + operator adds numbers, joins strings, and combines lists:

print(5 + 3)
print("Py" + "thon")
print([1, 2] + [3])

Expected output:

8
Python
[1, 2, 3]

How It Works Behind the Scenes

len(obj) works by calling the object's own special method, obj.__len__(). Each type — str, list, dict — implements __len__() in its own way. Your own classes can do the same:

class Playlist:
    def __init__(self, songs):
        self.songs = songs

    def __len__(self):
        return len(self.songs)

my_playlist = Playlist(["Song A", "Song B", "Song C"])
print(len(my_playlist))

Expected output:

3

Because Playlist defines __len__(), the built-in len() function works with it just like it works with lists and strings.

Polymorphism With Classes

In object-oriented programming, polymorphism usually means that several classes have a method with the same name, but each implements it differently.

Example: Different Animals, One Method Name

class Dog:
    def speak(self):
        print("Dog barks")

class Cat:
    def speak(self):
        print("Cat meows")

class Bird:
    def speak(self):
        print("Bird chirps")

animals = [Dog(), Cat(), Bird()]

for animal in animals:
    animal.speak()

Expected output:

Dog barks
Cat meows
Bird chirps

Why this is powerful:

  • The loop calls animal.speak() without checking what type of animal it is — there is no if isinstance(animal, Dog): ... elif ....
  • Each object responds to speak() in its own way.
  • Adding a new animal, such as a Cow class with its own speak() method, requires no changes to the loop.

Duck Typing

Notice that Dog, Cat, and Bird are unrelated classes — they do not share a parent. The loop works simply because each object has a speak() method.

This style is called duck typing, from the saying: "If it walks like a duck and quacks like a duck, it is a duck." Python cares about what an object can do, not what class it belongs to.

If an object in the list did not have a speak() method, Python would raise an AttributeError when the loop reached it.

Polymorphism Through Inheritance

Polymorphism is also commonly used with parent and child classes. Child classes inherit methods from the parent and can override them — replace them with their own versions.

Example: The Base Class

class Appliance:
    def __init__(self, name):
        self.name = name

    def operate(self):
        print("Appliance is operating")

The Child Classes

class WashingMachine(Appliance):
    def operate(self):
        print("Washing clothes")

class Refrigerator(Appliance):
    def operate(self):
        print("Cooling food")

class Microwave(Appliance):
    pass
  • WashingMachine and Refrigerator override operate() with their own behavior.
  • Microwave does not define operate(), so it inherits the parent's version.

Using Polymorphism

a1 = WashingMachine("LG Washer")
a2 = Refrigerator("Samsung Fridge")
a3 = Microwave("IFB Microwave")

for item in (a1, a2, a3):
    print(item.name)
    item.operate()

Expected output:

LG Washer
Washing clothes
Samsung Fridge
Cooling food
IFB Microwave
Appliance is operating

How Python chooses which operate() to run:

  1. For a1, Python looks in WashingMachine first, finds operate(), and runs it.
  2. For a2, Python finds operate() in Refrigerator.
  3. For a3, Python does not find operate() in Microwave, so it continues to the parent class Appliance and runs that version.

All three objects also share the name property set by the inherited __init__().

Practical Example: Payment Methods

Polymorphism is common in real applications. Here, an online store processes different payment types with the same code:

class Payment:
    def __init__(self, amount):
        self.amount = amount

    def pay(self):
        raise NotImplementedError("Subclasses must implement pay()")

class CardPayment(Payment):
    def pay(self):
        print(f"Charged ₹{self.amount} to card")

class UPIPayment(Payment):
    def pay(self):
        print(f"Requested ₹{self.amount} via UPI")

class CashOnDelivery(Payment):
    def pay(self):
        print(f"Collect ₹{self.amount} on delivery")

def checkout(payment):
    payment.pay()

for method in [CardPayment(1200), UPIPayment(450), CashOnDelivery(999)]:
    checkout(method)

Expected output:

Charged ₹1200 to card
Requested ₹450 via UPI
Collect ₹999 on delivery
  • checkout() works with any payment object that has a pay() method.
  • The base class's pay() raises NotImplementedError, which signals that every subclass is expected to provide its own version.
  • Supporting a new payment type means adding one new class — checkout() stays unchanged.

Benefits of Polymorphism

  • Flexibility — one piece of code works with many different types of objects.
  • Extensibility — new classes can be added without modifying existing code.
  • Readability — long if/elif chains that check types are replaced by simple method calls.
  • Reusability — common interfaces encourage consistent, reusable designs.

Common Mistakes

MistakeProblem
Different method names in related classes (bark(), meow())The objects cannot be used interchangeably
Different parameters for the same method nameCalls work for some objects but raise TypeError for others
Checking types with if isinstance(...) everywhereDefeats the purpose of polymorphism
Misspelling an overriding methodThe parent's version runs instead
An object without the expected methodAttributeError when the method is called
  • Python Inheritance — overriding methods in child classes
  • Python Class Methods — defining behavior in classes
  • Python Functions — built-in functions such as len() that work with many types
  • Python Encapsulation — hiding implementation details behind a common interface

0 Comments

Reviewed before they appear

No comments yet.

Python
Ask about this post
AI Ask about this post

Ask questions about Python Polymorphism and get answers drawn from it.

Signed-in readers only.