I have gone through the documentation of aiter and anext (New in version 3.10). But not understanding how to use them.
I have the following program:
import asyncio
async def get_range():
for i in range(10):
print(f"start {i}")
await asyncio.sleep(1)
print(f"end {i}")
yield i
class AIter:
def __init__(self, N):
self.i = 0
self.N = N
def __aiter__(self):
return self
async def __anext__(self):
i = self.i
print(f"start {i}")
await asyncio.sleep(1)
print(f"end {i}")
if i >= self.N:
raise StopAsyncIteration
self.i = 1
return i
async def main():
async for p in AIter(10):
print(f"finally {p}")
if __name__ == "__main__":
asyncio.run(main())
How can I use aiter
and anext
builtin here?
CodePudding user response:
Like with the regular synchronous iter
and next
builtins, you rarely need to use the new builtins directly. The async for
loop in main
calls the __aiter__
and __anext__
methods of your class already. If that does all you want, you're home free.
You only need to explicitly use aiter
and anext
if you are writing code that interacts with an asynchronous iterator in some way not directly supported by a async for
loop. For instance, here's an asynchronous generator that yields pairs of values from the iterable it's given:
async def pairwise(aiterable, default=None):
ait = aiter(aiterable) # get a reference to the iterator
async for x in ait:
yield x, await anext(ait, default) # get an extra value, yield a 2-tuple
If you loop on pairwise(AIter(10))
in your main
function, you'll find that it now prints tuples of numbers, like finally (0, 1)
. Before each tuple, you'll see two sets of the begin
and end
lines printed by the iterator class, one for each value that ends up in the paired result.