Programmation événementielle
La programmation événementielle se concentre sur les événements. Finalement, le déroulement du programme dépend des événements. Jusqu'à présent, nous avions affaire à un modèle d'exécution séquentielle ou parallèle, mais le modèle ayant le concept de programmation événementielle est appelé modèle asynchrone. La programmation événementielle dépend d'une boucle d'événements qui écoute toujours les nouveaux événements entrants. Le fonctionnement de la programmation événementielle dépend des événements. Une fois qu'un événement boucle, les événements décident de ce qu'il faut exécuter et dans quel ordre. L'organigramme suivant vous aidera à comprendre comment cela fonctionne -
Module Python - Asyncio
Le module Asyncio a été ajouté à Python 3.4 et fournit une infrastructure pour l'écriture de code simultané à un seul thread à l'aide de co-routines. Voici les différents concepts utilisés par le module Asyncio -
La boucle d'événements
Event-loop est une fonctionnalité permettant de gérer tous les événements dans un code de calcul. Il agit en boucle pendant l'exécution du programme entier et garde une trace de l'arrivée et de l'exécution des événements. Le module Asyncio autorise une seule boucle d'événements par processus. Voici quelques méthodes fournies par le module Asyncio pour gérer une boucle d'événements -
loop = get_event_loop() - Cette méthode fournira la boucle d'événements pour le contexte actuel.
loop.call_later(time_delay,callback,argument) - Cette méthode organise le rappel qui doit être appelé après les secondes time_delay données.
loop.call_soon(callback,argument)- Cette méthode organise un rappel qui doit être appelé dès que possible. Le rappel est appelé après le retour de call_soon () et lorsque le contrôle revient à la boucle d'événements.
loop.time() - Cette méthode permet de renvoyer l'heure actuelle en fonction de l'horloge interne de la boucle d'événements.
asyncio.set_event_loop() - Cette méthode définira la boucle d'événements du contexte actuel sur la boucle.
asyncio.new_event_loop() - Cette méthode créera et retournera un nouvel objet de boucle d'événement.
loop.run_forever() - Cette méthode fonctionnera jusqu'à ce que la méthode stop () soit appelée.
Exemple
L'exemple suivant de boucle d'événement aide à l'impression hello worlden utilisant la méthode get_event_loop (). Cet exemple est tiré de la documentation officielle de Python.
import asyncio
def hello_world(loop):
print('Hello World')
loop.stop()
loop = asyncio.get_event_loop()
loop.call_soon(hello_world, loop)
loop.run_forever()
loop.close()
Production
Hello World
Futures
Ceci est compatible avec la classe concurrent.futures.Future qui représente un calcul qui n'a pas été effectué. Il existe les différences suivantes entre asyncio.futures.Future et concurrent.futures.Future -
Les méthodes result () et exception () ne prennent pas d'argument timeout et lèvent une exception lorsque le futur n'est pas encore terminé.
Les rappels enregistrés avec add_done_callback () sont toujours appelés via la fonction call_soon () de la boucle d'événements.
La classe asyncio.futures.Future n'est pas compatible avec les fonctions wait () et as_completed () du package concurrent.futures.
Exemple
Voici un exemple qui vous aidera à comprendre comment utiliser la classe asyncio.futures.future.
import asyncio
async def Myoperation(future):
await asyncio.sleep(2)
future.set_result('Future Completed')
loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(Myoperation(future))
try:
loop.run_until_complete(future)
print(future.result())
finally:
loop.close()
Production
Future Completed
Coroutines
Le concept de coroutines dans Asyncio est similaire au concept d'objet Thread standard sous le module de threading. C'est la généralisation du concept de sous-programme. Une coroutine peut être suspendue pendant l'exécution pour qu'elle attende le traitement externe et retourne à partir du point où elle s'était arrêtée lorsque le traitement externe a été effectué. Les deux méthodes suivantes nous aident à implémenter des coroutines -
fonction def async ()
Il s'agit d'une méthode d'implémentation de coroutines sous le module Asyncio. Voici un script Python pour le même -
import asyncio
async def Myoperation():
print("First Coroutine")
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(Myoperation())
finally:
loop.close()
Production
First Coroutine
@ asyncio.coroutine décorateur
Une autre méthode d'implémentation des coroutines consiste à utiliser des générateurs avec le décorateur @ asyncio.coroutine. Voici un script Python pour le même -
import asyncio
@asyncio.coroutine
def Myoperation():
print("First Coroutine")
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(Myoperation())
finally:
loop.close()
Production
First Coroutine
Tâches
Cette sous-classe du module Asyncio est responsable de l'exécution des coroutines dans une boucle d'événements de manière parallèle. Le script Python suivant est un exemple de traitement de certaines tâches en parallèle.
import asyncio
import time
async def Task_ex(n):
time.sleep(1)
print("Processing {}".format(n))
async def Generator_task():
for i in range(10):
asyncio.ensure_future(Task_ex(i))
int("Tasks Completed")
asyncio.sleep(2)
loop = asyncio.get_event_loop()
loop.run_until_complete(Generator_task())
loop.close()
Production
Tasks Completed
Processing 0
Processing 1
Processing 2
Processing 3
Processing 4
Processing 5
Processing 6
Processing 7
Processing 8
Processing 9
Les transports
Le module Asyncio fournit des classes de transport pour implémenter différents types de communication. Ces classes ne sont pas thread-safe et toujours associées à une instance de protocole après l'établissement du canal de communication.
Voici différents types de transports hérités de BaseTransport -
ReadTransport - Il s'agit d'une interface pour les transports en lecture seule.
WriteTransport - Il s'agit d'une interface pour les transports en écriture seule.
DatagramTransport - Ceci est une interface pour l'envoi des données.
BaseSubprocessTransport - Similaire à la classe BaseTransport.
Les éléments suivants sont cinq méthodes distinctes de la classe BaseTransport qui sont par la suite transitoires sur les quatre types de transport -
close() - Il ferme le transport.
is_closing() - Cette méthode retournera true si le transport se ferme ou est déjà fermé.
get_extra_info(name, default = none) - Cela nous donnera des informations supplémentaires sur le transport.
get_protocol() - Cette méthode retournera le protocole actuel.
Protocoles
Le module Asyncio fournit des classes de base que vous pouvez sous-classer pour implémenter vos protocoles réseau. Ces classes sont utilisées en conjonction avec les transports; le protocole analyse les données entrantes et demande l'écriture des données sortantes, tandis que le transport est responsable des E / S et de la mise en mémoire tampon. Voici trois classes de protocole -
Protocol - Il s'agit de la classe de base pour l'implémentation de protocoles de streaming à utiliser avec les transports TCP et SSL.
DatagramProtocol - Il s'agit de la classe de base pour l'implémentation des protocoles de datagramme à utiliser avec les transports UDP.
SubprocessProtocol - Il s'agit de la classe de base pour l'implémentation de protocoles communiquant avec des processus enfants via un ensemble de canaux unidirectionnels.