Je souhaite utiliser le rendement du générateur et les fonctions asynchrones. J'ai lu ce sujet et écrit le code suivant:
import asyncio
async def createGenerator():
mylist = range(3)
for i in mylist:
await asyncio.sleep(1)
yield i*i
async def start():
mygenerator = await createGenerator()
for i in mygenerator:
print(i)
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(start())
except KeyboardInterrupt:
loop.stop()
pass
Mais j'ai eu l'erreur:
SyntaxError: 'rendement' dans une fonction asynchrone
Comment utiliser le générateur de rendement en fonction asynchrone?
Upd:
En commençant par Python 3.6, nous avons générateurs asynchrones et capables d'utiliser yield
directement dans les coroutines.
import asyncio
async def async_generator():
for i in range(3):
await asyncio.sleep(1)
yield i*i
async def main():
async for i in async_generator():
print(i)
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main())
finally:
loop.run_until_complete(loop.shutdown_asyncgens()) # see: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.shutdown_asyncgens
loop.close()
Ancienne réponse pour Python 3.5:
Vous ne pouvez pas yield
à l’intérieur des coroutines. Le seul moyen est d’implémenter Itérateur Asynchrone manuellement en utilisant __aiter__
/__anext__
méthodes magiques. Dans ton cas:
import asyncio
class async_generator:
def __init__(self, stop):
self.i = 0
self.stop = stop
async def __aiter__(self):
return self
async def __anext__(self):
i = self.i
self.i += 1
if self.i <= self.stop:
await asyncio.sleep(1)
return i * i
else:
raise StopAsyncIteration
async def main():
async for i in async_generator(3):
print(i)
if __== "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Sortie:
0
1
4
Nouveau Python 3.6 prend en charge les générateurs asynchrones.
PS: Au moment de la rédaction Python 3.6 est toujours en version bêta. Si vous êtes sur GNU/Linux ou OS X et que vous ne pouvez pas attendre, vous pouvez essayer un nouveau Python avec pyenv .
Cela devrait fonctionner avec python 3.6 (testé avec 3.6.0b1):
import asyncio
async def createGenerator():
mylist = range(3)
for i in mylist:
await asyncio.sleep(1)
yield i*i
async def start():
async for i in createGenerator():
print(i)
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(start())
except KeyboardInterrupt:
loop.stop()
pass