Асинхронный итератор может вызывать асинхронный код в своем методе __anext__
.
Асинхронные итераторы могут использоваться в асинхронном операторе цикла async for
.
object.__aiter__(self)
:Асинхронный метод object.__aiter__()
должен возвращать асинхронный итерируемый объект и семантически похож на метод __iter__()
простого итератора.
object.__anext__(self)
:Асинхронный метод object.__anext__()
семантически похож на метод __next__()
простого итератора, с той лишь разницей, что ондолжен возвращать следующее значение итератора в результате awaitable
.
Этот метод должен вызвать исключение StopAsyncIteration
, когда итерация закончена.
Пример асинхронного итерируемого объекта.
class Reader(): async def readline(self): ... def __aiter__(self): return self async def __anext__(self): val = await self.readline() if val == b'': raise StopAsyncIteration return val
Ниже приведен служебный класс, который преобразует обычный итерируемый объект в асинхронный. Хотя это не очень полезно, код иллюстрирует взаимосвязь между обычными итераторами и асинхронными итераторами.
import asyncio class AsyncIteratorWrapper(): def __init__(self, obj): self._it = iter(obj) def __aiter__(self): return self async def __anext__(self): try: value = next(self._it) except StopIteration: raise StopAsyncIteration return value async def it(sequence): async for letter in AsyncIteratorWrapper(sequence): print(letter) loop = asyncio.get_event_loop() try: loop.run_until_complete(asyncio.gather(it('012345'))) finally: loop.close()