Introduction au Polymorphisme
Le polymorphisme est un concept fondamental de la programmation orientée objet qui permet à différentes classes de répondre différemment à la même interface. En Python, il existe deux types principaux de polymorphisme :
- ✓ Le polymorphisme au runtime (duck typing)
- ✓ Le polymorphisme au compile-time (avec typing)
1. Polymorphisme au Runtime (Duck Typing)
Le polymorphisme au runtime en Python est basé sur le principe du "duck typing" : si un objet marche comme un canard et fait coin-coin comme un canard, alors c'est un canard. En d'autres termes, le type exact d'un objet importe moins que ses capacités.
# Exemple de polymorphisme au runtime
class Canard:
def faire_son(self):
return "Coin coin !"
class Chat:
def faire_son(self):
return "Miaou !"
class Chien:
def faire_son(self):
return "Wouf !"
def faire_parler_animal(animal):
# Aucune vérification de type n'est nécessaire
print(animal.faire_son())
# Les trois objets fonctionnent car ils ont la méthode faire_son()
canard = Canard()
chien = Chien()
chat = Chat()
faire_parler_animal(canard) # Coin coin !
faire_parler_animal(chien) # Wouf !
faire_parler_animal(chat) # Miaou !
2. Polymorphisme au Compile-time (Typing)
Les annotations du module typing permettent d'exprimer une interface attendue et de la faire analyser avant l'exécution par un outil tel que Pyright ou mypy. L'interpréteur Python ne les impose pas lui-même à l'exécution.
from typing import Protocol, List
# Définition d'un protocole (interface)
class Animal(Protocol):
def faire_son(self) -> str: ...
class Chien:
def faire_son(self) -> str:
return "Wouf !"
class Chat:
def faire_son(self) -> str:
return "Miaou !"
# Un vérificateur de types peut contrôler cette interface avant l'exécution.
def faire_parler_animaux(animaux: List[Animal]) -> None:
for animal in animaux:
print(animal.faire_son())
animaux: List[Animal] = [Chien(), Chat()]
faire_parler_animaux(animaux)
Différences Clés entre Runtime et Compile-time
| Aspect | Runtime (Duck Typing) | Compile-time (Typing) |
|---|---|---|
| Vérification | Pendant l'exécution | Analyse statique optionnelle avant l'exécution |
| Flexibilité | Très flexible | Plus strict |
| Sécurité | Moins sûr | Plus sûr |
| Performance | Pas de vérification préalable | Pas de coût imposé par Python à l'exécution |
Avantages et Inconvénients
Runtime Polymorphism
- ✓ Plus flexible et dynamique
- ✓ Code plus concis
- ✓ Facilite le test et le mocking
- ✗ Risque d'erreurs à l'exécution
- ✗ Documentation moins explicite
Compile-time Polymorphism
- ✓ Détection précoce des erreurs
- ✓ Meilleure documentation du code
- ✓ Support IDE amélioré
- ✗ Code plus verbeux
- ✗ Moins flexible
Quand Utiliser Quel Type ?
Le choix entre runtime et compile-time dépend de vos besoins :
Utilisez le Runtime Polymorphism quand :
- ✓ Vous avez besoin de maximum de flexibilité
- ✓ Vous écrivez des tests unitaires
- ✓ Vous développez un petit projet
Utilisez le Compile-time Polymorphism quand :
- ✓ Vous travaillez sur un grand projet
- ✓ La sécurité des types est cruciale
- ✓ Vous voulez une meilleure maintenabilité
Points Clés à Retenir
- Le polymorphisme runtime est plus pythonique et flexible
- Le polymorphisme compile-time offre plus de sécurité
- Les deux approches peuvent être combinées selon les besoins
- Le choix dépend de la taille et des exigences du projet
Prochaines Étapes
- Exploration des design patterns polymorphiques
- Utilisation avancée des protocoles typing
- Meilleures pratiques pour le polymorphisme