Qu'est-ce que la programmation asynchrone en Python ?
La programmation asynchrone est une méthode d'écriture de code où les tâches ne s'exécutent pas de manière séquentielle, mais en parallèle ou en attendant des événements sans bloquer le fil d'exécution principal. Dans le développement moderne, l'utilisation efficace des ressources et du temps d'exécution des applications est essentielle.
La programmation asynchrone permet de :
- Accélérer l'exécution des tâches
- Améliorer la réactivité des programmes
- Utiliser les ressources système de manière rationnelle
Les principaux avantages de l'asynchrone
Domaines d'application
La programmation asynchrone est particulièrement utile pour les opérations d'entrée-sortie :
- Gestion des fichiers
- Requêtes réseau (API HTTP)
- Interaction avec les bases de données
- Traitement des WebSockets
- Parsing de gros volumes de données
Différences avec le multithreading
Contrairement au multithreading, l'asynchrone ne nécessite pas la création de threads ou de processus supplémentaires. Cela réduit la charge système et évite les problèmes de verrouillage et de synchronisation des données entre les threads.
Comment fonctionne l'asynchrone en Python
Python offre un support natif de la programmation asynchrone via le module asyncio, officiellement ajouté à la bibliothèque standard à partir de la version 3.4.
Concepts clés
async def— définit une fonction asynchrone (coroutine)await— indique qu'il faut attendre l'exécution d'une coroutineasyncio— module standard pour gérer les tâches asynchronesevent loop— boucle d'événements qui gère l'exécution des coroutines
Exemple de base d'une fonction asynchrone
import asyncio
async def saluer():
print("Bonjour !")
await asyncio.sleep(1)
print("1 seconde s'est écoulée")
asyncio.run(saluer())
Dans cet exemple, await asyncio.sleep(1) simule l'attente d'une opération coûteuse, comme une requête réseau.
Créer et utiliser des fonctions asynchrones
Définir une fonction asynchrone
Pour créer une fonction asynchrone, utilisez le mot-clé async avant la définition de la fonction :
async def fetch_data():
print("Demande de données...")
await asyncio.sleep(2)
print("Données reçues")
Appeler une fonction asynchrone
L'appel d'une fonction asynchrone se fait via asyncio.run() :
asyncio.run(fetch_data())
Exécution parallèle de plusieurs tâches
Utilisation de asyncio.gather()
Pour lancer plusieurs coroutines en parallèle, utilisez asyncio.gather() :
async def tache(nom, delai):
print(f"Début de la tâche {nom}")
await asyncio.sleep(delai)
print(f"Tâche {nom} terminée")
async def main():
await asyncio.gather(
tache("A", 2),
tache("B", 1),
tache("C", 3)
)
asyncio.run(main())
Alternatives pour lancer des tâches
En plus de asyncio.gather(), vous pouvez utiliser :
asyncio.create_task()— pour créer des tâches individuellesasyncio.wait()— pour attendre la fin des tâches avec des options supplémentairesasyncio.as_completed()— pour obtenir les résultats au fur et à mesure qu'ils sont prêts
Itérateurs et générateurs asynchrones
Créer un itérateur asynchrone
Pour traiter des flux de données de manière asynchrone, utilisez les itérateurs asynchrones :
class AsyncCounter:
def __init__(self, max_count):
self.max_count = max_count
s