Programmazione guidata dagli eventi

La programmazione basata sugli eventi si concentra sugli eventi. Alla fine, il flusso del programma dipende dagli eventi. Fino ad ora, abbiamo avuto a che fare con un modello di esecuzione sequenziale o parallelo, ma il modello che ha il concetto di programmazione guidata dagli eventi è chiamato modello asincrono. La programmazione guidata dagli eventi dipende da un ciclo di eventi che è sempre in ascolto dei nuovi eventi in arrivo. Il funzionamento della programmazione guidata dagli eventi dipende dagli eventi. Una volta che un evento si ripete, gli eventi decidono cosa eseguire e in quale ordine. Il seguente diagramma di flusso ti aiuterà a capire come funziona -

Modulo Python - Asyncio

Il modulo Asyncio è stato aggiunto in Python 3.4 e fornisce l'infrastruttura per la scrittura di codice simultaneo a thread singolo utilizzando le co-routine. Di seguito sono riportati i diversi concetti utilizzati dal modulo Asyncio:

Il ciclo degli eventi

Event-loop è una funzionalità per gestire tutti gli eventi in un codice di calcolo. Agisce in modo continuo durante l'esecuzione dell'intero programma e tiene traccia dell'arrivo e dell'esecuzione degli eventi. Il modulo Asyncio consente un singolo ciclo di eventi per processo. Di seguito sono riportati alcuni metodi forniti dal modulo Asyncio per gestire un ciclo di eventi -

  • loop = get_event_loop() - Questo metodo fornirà il ciclo di eventi per il contesto corrente.

  • loop.call_later(time_delay,callback,argument) - Questo metodo organizza la richiamata che deve essere chiamata dopo il dato time_delay secondi.

  • loop.call_soon(callback,argument)- Questo metodo prevede una richiamata che deve essere richiamata il prima possibile. Il callback viene chiamato dopo che call_soon () ritorna e quando il controllo ritorna al ciclo di eventi.

  • loop.time() - Questo metodo viene utilizzato per restituire l'ora corrente in base all'orologio interno del loop di eventi.

  • asyncio.set_event_loop() - Questo metodo imposterà il loop degli eventi per il contesto corrente sul loop.

  • asyncio.new_event_loop() - Questo metodo creerà e restituirà un nuovo oggetto loop di eventi.

  • loop.run_forever() - Questo metodo verrà eseguito fino a quando non viene chiamato il metodo stop ().

Esempio

Il seguente esempio di loop di eventi aiuta nella stampa hello worldutilizzando il metodo get_event_loop (). Questo esempio è tratto dalla documentazione ufficiale di 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()

Produzione

Hello World

Futures

Ciò è compatibile con la classe concurrent.futures.Future che rappresenta un calcolo che non è stato completato. Ci sono le seguenti differenze tra asyncio.futures.Future e concurrent.futures.Future -

  • I metodi result () e exception () non accettano un argomento di timeout e sollevano un'eccezione quando il futuro non è ancora finito.

  • I callback registrati con add_done_callback () vengono sempre chiamati tramite call_soon () del ciclo di eventi.

  • La classe asyncio.futures.Future non è compatibile con le funzioni wait () e as_completed () nel pacchetto concurrent.futures.

Esempio

Quello che segue è un esempio che ti aiuterà a capire come usare 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()

Produzione

Future Completed

Coroutines

Il concetto di coroutine in Asyncio è simile al concetto di oggetto Thread standard sotto il modulo threading. Questa è la generalizzazione del concetto di subroutine. Una coroutine può essere sospesa durante l'esecuzione in modo che attenda l'elaborazione esterna e ritorni dal punto in cui si era interrotta quando l'elaborazione esterna è stata eseguita. I due modi seguenti ci aiutano a implementare le coroutine:

funzione async def ()

Questo è un metodo per l'implementazione delle coroutine nel modulo Asyncio. Di seguito è riportato uno script Python per lo stesso -

import asyncio

async def Myoperation():
   print("First Coroutine")

loop = asyncio.get_event_loop()
try:
   loop.run_until_complete(Myoperation())

finally:
   loop.close()

Produzione

First Coroutine

@ decoratore asyncio.coroutine

Un altro metodo per l'implementazione delle coroutine consiste nell'utilizzare i generatori con il decoratore @ asyncio.coroutine. Di seguito è riportato uno script Python per lo stesso -

import asyncio

@asyncio.coroutine
def Myoperation():
   print("First Coroutine")

loop = asyncio.get_event_loop()
try:
   loop.run_until_complete(Myoperation())

finally:
   loop.close()

Produzione

First Coroutine

Compiti

Questa sottoclasse del modulo Asyncio è responsabile dell'esecuzione di coroutine all'interno di un ciclo di eventi in modo parallelo. Il seguente script Python è un esempio di elaborazione di alcune attività in parallelo.

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()

Produzione

Tasks Completed
Processing 0
Processing 1
Processing 2
Processing 3
Processing 4
Processing 5
Processing 6
Processing 7
Processing 8
Processing 9

Trasporti

Il modulo Asyncio fornisce classi di trasporto per implementare vari tipi di comunicazione. Queste classi non sono thread-safe e sono sempre associate a un'istanza di protocollo dopo aver stabilito il canale di comunicazione.

Di seguito sono riportati diversi tipi di trasporto ereditati da BaseTransport:

  • ReadTransport - Questa è un'interfaccia per i trasporti di sola lettura.

  • WriteTransport - Questa è un'interfaccia per i trasporti di sola scrittura.

  • DatagramTransport - Questa è un'interfaccia per l'invio dei dati.

  • BaseSubprocessTransport - Simile alla classe BaseTransport.

I seguenti sono cinque metodi distinti della classe BaseTransport che sono successivamente transitori tra i quattro tipi di trasporto:

  • close() - Chiude il trasporto.

  • is_closing() - Questo metodo restituirà true se il trasporto si sta chiudendo o è già chiuso.

  • get_extra_info(name, default = none) - Questo ci darà alcune informazioni extra sul trasporto.

  • get_protocol() - Questo metodo restituirà il protocollo corrente.

Protocolli

Il modulo Asyncio fornisce classi base che puoi sottoclassare per implementare i tuoi protocolli di rete. Queste classi vengono utilizzate insieme ai trasporti; il protocollo analizza i dati in entrata e richiede la scrittura dei dati in uscita, mentre il trasporto è responsabile dell'I / O e del buffering effettivi. Di seguito sono riportate tre classi di protocollo:

  • Protocol - Questa è la classe base per l'implementazione dei protocolli di streaming da utilizzare con i trasporti TCP e SSL.

  • DatagramProtocol - Questa è la classe base per l'implementazione dei protocolli di datagramma da utilizzare con i trasporti UDP ..

  • SubprocessProtocol - Questa è la classe base per l'implementazione di protocolli che comunicano con i processi figli attraverso un insieme di pipe unidirezionali.