How to use 'yield' inside async function?

匿名 (未验证) 提交于 2019-12-03 07:36:14

问题:

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 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!