Python Polymorphism
By Flavio Copes
Learn how polymorphism works in Python: defining the same method, like eat(), on different classes so you can call it without knowing each object's type.
Polymorphism means you can call the same method on objects of different classes, and each object responds in its own way. It’s an important concept in object-oriented programming.
The word comes from Greek and means “many forms”. The same method call takes many forms, depending on the object that receives it.
Why is this useful?
Suppose your program manages animals. Dogs and cats eat different food, but they both eat. If both classes define an eat() method, the code that feeds the animals doesn’t need to care which animal it’s feeding.
We can define the same method on different classes:
class Dog:
def eat(self):
print('Eating dog food')
class Cat:
def eat(self):
print('Eating cat food')
Then we create objects and call eat() regardless of the class each object belongs to, and we get different results:
animal1 = Dog()
animal2 = Cat()
animal1.eat() # Eating dog food
animal2.eat() # Eating cat food
We built a generalized interface, and we do not need to know if an animal is a Cat or a Dog.
Polymorphism in a loop
This gets more interesting with a list of mixed objects:
animals = [Dog(), Cat(), Dog()]
for animal in animals:
animal.eat()
The output is:
Eating dog food
Eating cat food
Eating dog food
Each object runs its own version of eat(). No if statements checking types.
Duck typing
Notice that Dog and Cat don’t share a parent class. Python doesn’t require one. As long as the object has an eat() method, the call works.
This is called duck typing: if it walks like a duck and quacks like a duck, Python treats it as a duck.
In languages like Java you’d need a common interface or base class. In Python, the method existing is enough.
The flip side: if an object doesn’t have the method, the error only shows up when you call it:
class Fish:
pass
Fish().eat()
# AttributeError: 'Fish' object has no attribute 'eat'
A common mistake
Be careful to include self as the first parameter when you define the method. Without it, this call fails:
class Dog:
def eat():
print('Eating dog food')
Dog().eat()
# TypeError: Dog.eat() takes 0 positional arguments but 1 was given
Python passes the object itself as the first argument automatically. The method must have a parameter ready to receive it, and by convention we name it self.
Related posts about python: