可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to use generator yield and async functions. I read this topic, and wrote next code:
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
But i got the error:
SyntaxError: 'yield' inside async function
How to use yield generator in async function?
回答1:
Upd:
Starting with Python 3.6 we have asynchronous generators and able to use yield
directly inside 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.AbstractEventLoop.shutdown_asyncgens loop.close()
Old answer for Python 3.5:
You can't yield
inside coroutines. Only way is to implement Asynchronous Iterator manually using __aiter__
/__anext__
magic methods. In your case:
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
Output:
0 1 4
Here're two more examples: 1, 2
回答2:
New Python 3.6 comes with support for asynchronous generators.
PEP 0525
What's new in Python 3.6
PS: On the moment of writing Python 3.6 is still beta. If you are on GNU/Linux or OS X and you cannot wait you can try new Python with pyenv.
回答3:
This should work with python 3.6 (tested with 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