8.11. Async yineleyiciler¶
Async yineleyici, bir yineleyicinin asyncio sürümüdür. Python Genel Bakış sayfasında eşzamanlı yineleyici protokolü – __iter__ ve __next__ – ile onu süren for döngüsü tanıtılmıştı. Async yineleyiciler her adıma bir await ekler, böylece yineleyici değerler arasında olay döngüsünü engellemeden bekleyebilir.
8.11.1. Protokol¶
Bir sınıf, şunları uyguladığında bir async yineleyicidir
__aiter__(self)– yineleyici nesnesini döndürür, genellikleself.async def __anext__(self)– bir sonraki değeri döndürür veya başka değer kalmadığındaStopAsyncIterationyükseltir.
Buna karşılık gelen döngü yapısı async for şeklindedir:
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)
async for döngüsü __anext__ çağrılarının her birini await eder, böylece döngüyü çalıştıran eşyordam, tıpkı diğer await ifadelerinde olduğu gibi, değerler arasında kontrolü olay döngüsüne bırakır.
8.11.2. Ne zaman başvurulur¶
Uygulamanın zaman içinde gelen bir veri kaynağı olduğu ve tüketicinin onu tembel biçimde yinelemesi gerektiği her durumda. Her dönemde bir örnek üreten bir sensör, mesajlar ileten bir ağ soketi, bir çerçeve üreteci – while True: x = await source.next(); process(x) biçiminin uyduğu her yerde, async for x in source daha temiz bir yazımdır.
Sonlu bir bitiş koşuluna kadar değer yayan kaynaklar için yineleyici StopAsyncIteration yükseltir ve async for normal şekilde sonlanır. Hiç bitmeyen kaynaklar için – sürekli bir sensör akışı, uzun süre çalışan bir abonelik – döngü, içinde bulunduğu eşyordam iptal edilene veya görevi sökülene kadar çalışır.