2015-04-20 12 views
6

I Googled python coroutine, e visto solo generatori (Quasi quasi tutti gli esempi utilizzano yield senza asyncio.)Si può pensare che l'asyncio.coroutine di Python sia un generatore?

sono davvero la stessa cosa?

Qual è la differenza tra asyncio.coroutine e un generatore?

+0

Questa domanda è un po 'ampia al momento. Potrebbe essere meglio modificarlo per coprire solo uno o due punti specifici (forse in relazione a cosa vuoi fare con 'yieldFromRequests'?). Consiglierei di leggere [PEP 380] (https://www.python.org/dev/peps/pep-0380/), che ha introdotto 'yield from' nella lingua e [PEP 3156] (https: // www .python.org/dev/peps/pep-3156 /), che ha introdotto 'asyncio'. Tra questi due documenti dovrebbe essere data risposta alla maggior parte delle domande. – dano

+0

Anche di interesse potrebbe essere [PEP 492] (https://www.python.org/dev/peps/pep-0492), che è una proposta per rendere la sintassi per le coroutine più distinta dalla sintassi per i generatori - il che significa non più usando 'yield from' per implementare le coroutine. Il PEP non è stato ancora accettato, anche se sembra che verrà accettato presto (forse anche in tempo per Python 3.5). – dano

+0

@dano Ho modificato la domanda. Inserisco la domanda separatamente. – item4

risposta

3

La maggior parte delle implementazioni di coroutine in Python (comprese quelle fornite da asyncio e tornado) sono implementate utilizzando i generatori. Questo è stato il caso dal PEP 342 - Coroutines via Enhanced Generators che ha reso possibile l'invio di valori negli oggetti del generatore in esecuzione, che ha consentito l'implementazione di semplici coroutine. Coroutine tecnicamente sono generatori, sono solo progettati per essere utilizzati in un modo molto diverso. Infatti, il PEP per asyncioexplicitly states this:

Un coroutine è un generatore che segue determinate convenzioni.

asyncio.coroutineè un generatore. Letteralmente:

La differenza, ancora una volta, sta nel modo in cui le due cose devono essere utilizzate. Cercando di iterare su un asyncio.coroutine come un generatore normale non funzionerà:

>>> next(a) 
Future<PENDING> 
>>> next(a) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 3, in mycoro 
    File "/usr/lib/python3.4/asyncio/tasks.py", line 548, in sleep 
    return (yield from future) 
    File "/usr/lib/python3.4/asyncio/futures.py", line 349, in __iter__ 
    assert self.done(), "yield from wasn't used with future" 
AssertionError: yield from wasn't used with future 

Chiaramente, non siete fatti per scorrere su di esso. Si intende solo yield from o registrarlo con il ciclo degli eventi asyncio utilizzando asyncio.create_task o asyncio.async.

Come accennato in precedenza, è stato possibile implementare coroutine utilizzando i generatori dal momento che PEP 342, che era molto prima dello asyncio o yield from, si presentava; questa caratteristica è stata aggiunta nel 2005. asyncio e yield from basta aggiungere funzionalità che semplificano la scrittura delle coroutine.

Problemi correlati