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.