Python Polymorphism
In this page:
What is Polymorphism?
Polymorphism means objects of different classes can respond to the exact same method call in their own way -- calling .speak() on a Dog and a Cat runs different code in each, but the calling code doesn't need to know or care which specific class it's dealing with.
Example: What is Polymorphism?
class Dog:
def speak(self):
print("Woof")
class Cat:
def speak(self):
print("Meow")
for animal in [Dog(), Cat()]:
animal.speak()
Polymorphism with Inheritance
The most common form of polymorphism pairs naturally with inheritance: a base class defines a method, and each subclass overrides it with its own version, so a loop that calls animal.speak() on a mixed list of Dog and Cat objects gets the right sound for each without any if/else type checking.
Example: Polymorphism with Inheritance
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
print("Woof")
class Cat(Animal):
def speak(self):
print("Meow")
for animal in [Dog(), Cat()]:
animal.speak()
Duck Typing
Python doesn't require an object to belong to a specific class or inherit from a specific base to be used somewhere -- if it has the methods being called on it, that's enough. This 'duck typing' means you can pass any object with a .read() method to code expecting a file, whether or not it's literally a file.
Example: Duck Typing
class Duck:
def read(self):
print("Duck pretending to read")
def process(obj):
obj.read()
process(Duck())
Built-in Polymorphic Functions
Functions like len() and operators like + are polymorphic in the sense that they behave differently depending on the type they're given -- len() counts characters for a string but items for a list, and + concatenates strings but adds numbers, all through the same syntax.
Example: Built-in Polymorphic Functions
print(len("hello"))
print(len([1, 2, 3]))
print("a" + "b")
print(1 + 2)
Abstract Base Classes
An abstract base class defines method signatures that subclasses are required to implement, using the abc module -- this gives you compile-time-like safety that every subclass genuinely provides the methods your polymorphic code expects, rather than failing at runtime with an AttributeError.
Example: Abstract Base Classes
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side ** 2
print(Square(4).area())
Chapter Quiz — Complete all 11 topics to unlock
0/11 topics done
Complete these topics first: