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 asyncio
explicitly 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.
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
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
@dano Ho modificato la domanda. Inserisco la domanda separatamente. – item4