lettura simple

Le coroutine in Python

Le coroutine sono funzioni che sospendono l'esecuzione quando incontrano l'istruzione yield, per poi riprendere l'esecuzione dallo stesso punto alla chiamata successiva

Qual è la differenza tra coroutine e generatori? Entrambe conservano il namespace locale, ossia i valori assegnati alle variabili locali, quando restituiscono il controllo al programma chiamante. Tuttavia, i generatori restituiscono un valore al codice chiamante mentre le coroutine lo ricevono oppure lo consumano.

Nelle coroutine l'istruzione yield va inserita sul lato destro dell'assegnazione

x = (yeld)

o come singola istruzione.

yeld

Come funziona una coroutine?

Quando chiami la coroutine, questa restituisce un generatore che puoi utilizzare con i seguenti metodi:

  • send()
    Riprende l'esecuzione della coroutine passandogli un valore.
  • __next__()
    Riprende l'esecuzione della coroutine senza passargli un valore.

A cosa servono le coroutine? Le coroutine sono utilizzate per scrivere codice asincrono. Ti forniscono un meccanismo per sospendere e riprendere l'esecuzione di funzioni in punti specifici,  rendendo più facile la gestione di compiti concorrenti e asincroni in applicazioni multithreading o basate su eventi.

Il metodo __next__()

Il metodo __next__() ti permette di chiamare la coroutine senza passargli un valore da consumare.

oggetto.__next__()

Ti faccio un altro esempio pratico.

Definisci questa funzione coroutine()

def countdown():
    n=10
    while n > 0:
        yield
        n -= 1
        print(n)

La coroutine si chiama "countdown()"

Crea la coroutine nell'oggetto x. 

x = countdown()

La prima chiamata con il metodo __next__() inizializza la funzione e si blocca al primo yield che incontra.

Alla variabile n viene assegnato il numero 10.

x.__next__()

La seconda chiamata con il metodo __next__() riprende l'esecuzione dopo l'istruzione yield.

Quindi, decrementa la variabile n di una unità e stampa il risultato.

x.__next__()

9

La coroutine viene nuovamente sospesa quando il ciclo while itera incontrando nuovamente l'istruzione yield.

La terza chiamata con il metodo __next__() riprende l'esecuzione dopo l'istruzione yield, decrementa n e stampa il risultato.

x.__next__()

8

Come puoi notare, ogni volta che viene richiamata la funzione countdown() riprende l'esecuzione dal punto in cui è stata sospesa e ricorda tutti i valori delle variabili locali.

Le coroutine con il metodo send()

Il metodo send() ti permette di chiamare la coroutine passandogli un valore da consumare tra le parentesi tonde.

oggetto.send()

Ti faccio un altro esempio pratico.

Definisci questa coroutine con due istruzioni yield al suo interno.

def countdown():
    # riceve un valore dalla chiamata
    n=yield
    while n > 0:
        # attende la prossima chiamata
        yield
        n -= 1
        print(n)

La coroutine si chiama sempre "countdown()" ed è sostanzialmente una funzione.

La prima istruzione yield attende un valore da consumare mentre la seconda istruzione yield lo consuma.

Per utilizzarla devi creare un generatore.

oggetto = countdown()

Una volta creato il generatore devi iniziarlo con una chiamata a vuoto send(None).

oggetto.send(None)

In alternativa, puoi inizializzare il generatore anche usando la funzione next.

next(oggetto)

A questo punto puoi inviare il valore da consumare alla coroutine tramite il metodo send().

Ad esempio, invia il valore 10

oggetto.send(10)

La coroutine riceve il valore 10 e lo assegna alla variabile n.

A questo punto, la coroutine inizia il ciclo while e sospende l'esecuzione quando incontra l'altra istruzione yield.

Per continuare l'esecuzione devi chiamare la coroutine con i metodi send() oppure __next__()

oggetto.__next__()

La coroutine riprende l'esecuzione dall'istruzione yield, decrementa il valore della variabile n e stampa il risultato.

9

Nell'iterazione successiva del ciclo while la coroutine si interrompe nuovamente quando incontra yield e attende una nuova chiamata.

oggetto.__next__()

8

Ogni volta che chiami la coroutine, questa decrementa il valore della variabile n e stampa il risultato.

Per concludere l'esecuzione della coroutine chiama il metodo close()

oggetto.close()

Questo comando termina l'esecuzione della coroutine.




Se qualcosa non ti è chiaro, scrivi la tua domanda nei commenti.




FacebookTwitterLinkedinLinkedin