简体   繁体   中英

Using next() on an async generator

A generator can be iterated step by step by using the next() built-in function. For example:

def sync_gen(n):
    """Simple generator"""
    for i in range(n):
        yield i**2

sg = sync_gen(4)
print(next(sg)) # -> 0
print(next(sg)) # -> 1
print(next(sg)) # -> 4

Using next() on an asynchronous generator does not work:

import asyncio

async def async_gen(n):
    for i in range(n):
        yield i**2

async def main():
    print("Async for:")
    async for v in async_gen(4):  # works as expected
        print(v)

    print("Async next:")
    ag = async_gen(4)
    v = await next(ag) # raises: TypeError: 'async_generator' object is not an iterator
    print(v)

asyncio.run(main())

Does something like v = await async_next(ag) exist to obtain same behavior as with normal generators?

Since Python 3.10 there are aiter(async_iterable) and awaitable anext(async_iterator) builtin functions , analogous to iter and next , so you don't have to rely on the async_iterator.__anext__() magic method anymore. This piece of code works in python 3.10:

import asyncio


async def async_gen(n):
    for i in range(n):
        yield i**2


async def main():
    print("Async next:")
    ag = async_gen(4)
    print(await anext(ag))


asyncio.run(main())

As stated next will not work on an async generator as it's not an iterator.

If you must use a function you could create a helper function instead of using the __anext__ function outwrite:

async def anext(ait):
    return await ait.__anext__()

ag = async_gen(4)
v = await anext(ag)
print(v)

PEP525 Asynchronous Generator Object describes __anext__() method:

agen.__anext__() : Returns an awaitable, that performs one asynchronous generator iteration when awaited.

So it's possible to call it:

print("Async next:")
ag = async_gen(4)
v = await ag.__anext__()
print(v)

But as discussed here it is not recommended

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM