Сообщить об ошибке.

Асинхронный async for в Python

Асинхронный итерируемый объект может вызывать асинхронный код в своей реализации __aiter__(), а асинхронный итератор может вызывать асинхронный код в своем методе __anext__().

Асинхронный оператор async for ... in обеспечивает удобную итерацию по асинхронным итераторам и асинхронным генераторам.

Асинхронный оператор async for ... in действует только в теле асинхронной функции (сопрограммы) async def.

async for TARGET in ITER:
    SUITE
else:
    SUITE2

Семантически эквивалентно:

iter = (ITER)
iter = type(iter).__aiter__(iter)
running = True

while running:
    try:
        TARGET = await type(iter).__anext__(iter)
    except StopAsyncIteration:
        running = False
    else:
        SUITE
else:
    SUITE2

Конечно же, для асинхронного async for можно использовать короткий синтаксис, который подробно описан в списках-выражениях. Действует только в теле асинхронной функции (сопрограммы) async def.

# асинхронное выражение-генератор: 
(i ** 2 async for i in agen()).
# асинхронное список-выражение: 
[i async for i in agen()]
# асинхронное словарь-выражение: 
{i: i ** 2 async for i in agen()} ;
# асинхронное выражение-множество:
 {i async for i in agen()}

Теперь разрешено использование выражений await как в асинхронном, так и в синхронном понимании коротких выражений генераторов.

# на примере списка-выражения
result = [await fun() for fun in funcs]
result = [await fun() for fun in funcs if await smth]
result = [await fun() async for fun in funcs]
result = [await fun() async for fun in funcs if await smth]

Примеры:

import asyncio

async def ticker(delay, to):
    for i in range(to):
        yield (i, delay)
        await asyncio.sleep(delay)
        
async def run(k):
    # пример асинхронного for
    async for i in ticker(k, 10):
        print(i)
        
loop = asyncio.get_event_loop()
try:
    loop.run_until_complete(asyncio.gather(run(0.5),run(1)))
finally:
    loop.close()
    
# (0, 0.5)
# (0, 1)
# (1, 0.5)
# (1, 1)
# (2, 0.5)
# (3, 0.5)
# (2, 1)
# (4, 0.5)
# (5, 0.5)
# (3, 1)
# (6, 0.5)
# (7, 0.5)
# (4, 1)
# (8, 0.5)
# (9, 0.5)
# (5, 1)
# (6, 1)
# (7, 1)
# (8, 1)
# (9, 1)