8.11. Asinkroni iteratori¶
Asinkroni iterator je asyncio inačica iteratora. Pregled Pythona predstavio je sinkroni protokol iteratora – __iter__ i __next__ – te petlju for koja ga pogoni. Asinkroni iteratori dodaju await svakom koraku, tako da iterator može čekati između vrijednosti bez blokiranja petlje događaja.
8.11.1. Protokol¶
Klasa je asinkroni iterator kada implementira
__aiter__(self)– vraća objekt iteratora, običnoself.async def __anext__(self)– vraća sljedeću vrijednost ili podižeStopAsyncIterationkada ih više nema.
Odgovarajuća konstrukcija petlje je async for
import asyncio
class FrameCounter:
"""Yield N integers, one per frame period."""
def __init__(self, n, period_ms):
self._n = n
self._period_ms = period_ms
self._i = 0
def __aiter__(self):
return self
async def __anext__(self):
if self._i >= self._n:
raise StopAsyncIteration
await asyncio.sleep_ms(self._period_ms)
self._i += 1
return self._i
async def main():
async for n in FrameCounter(5, 200):
print(n)
Petlja async for čeka svaki poziv na __anext__, tako da korutina koja izvodi petlju prepušta kontrolu petlji događaja između vrijednosti, baš kao i svaki drugi await.
8.11.2. Kada ga upotrijebiti¶
Kad god aplikacija ima izvor podataka koji pristižu tijekom vremena, a potrošač bi ih trebao iterirati lijeno. Senzor koji proizvodi uzorak po razdoblju, mrežna utičnica koja isporučuje poruke, generator sličica – gdje god odgovara oblik while True: x = await source.next(); process(x), async for x in source je čišći način zapisa.
Za izvore koji emitiraju do konačnog uvjeta završetka, iterator podiže StopAsyncIteration i async for normalno izlazi. Za izvore koji nikada ne završavaju – kontinuirani tok senzora, dugotrajna pretplata – petlja se izvodi sve dok se korutina u kojoj živi ne otkaže ili dok se njezin zadatak ne ukine.