Polymorphisme en Python (et en programmation orientée objet en général) désigne la capacité d’un même nom (fonction, méthode, opérateur) à s’appliquer à des objets de types différents, en s’adaptant à leur comportement.

👉 Littéralement : “plusieurs formes”.
1. Exemple simple avec les fonctions intégrées

Beaucoup de fonctions Python sont polymorphes par nature :

print(len("Bonjour"))   # 7, car c'est une chaîne
print(len([1, 2, 3]))   # 3, car c'est une liste
print(len({"a": 1, "b": 2}))  # 2, car c'est un dictionnaire

👉 La même fonction len() fonctionne avec différents types, mais son comportement dépend de l’objet.

2. Polymorphisme avec les classes

En POO, on définit différentes classes qui implémentent une même méthode mais de façon différente :

class Chien:
    def parler(self):
        return "Wouf!"

class Chat:
    def parler(self):
        return "Miaou!"

def faire_parler(animal):
    print(animal.parler())

# Utilisation
rex = Chien()
felix = Chat()

faire_parler(rex)    # Wouf!
faire_parler(felix)  # Miaou!

Ici, faire_parler() n’a pas besoin de savoir si c’est un Chien ou un Chat, il appelle juste parler() : polymorphisme par héritage / duck typing.

3. Polymorphisme par surcharge d’opérateurs

Les opérateurs en Python sont aussi polymorphes :

print(3 + 4)        # addition d'entiers
print("a" + "b")    # concaténation de chaînes
print([1, 2] + [3]) # fusion de listes

Derrière, chaque type définit sa propre version de __add__.

Pour finir :

Le polymorphisme permet d’utiliser une même interface (même nom de fonction, opérateur, méthode) avec des objets différents.

  • les fonctions intégrées (len, print, etc.)
  • le duck typing (“si ça marche comme un canard, je le traite comme un canard”)
  • la redéfinition de méthodes dans les classes (héritage ou non)
  • la surcharge d’opérateurs (__add__, __str__, etc.)