Pythonで async
や await
を学んでいるときに、async for
という構文を見かけて「これ何だろう?」と気になった方もいるかもしれません。
この記事では、非同期イテレータとは何か、そしてasync for の使い方について、自分の学習記録として整理してみました。
🔍 async for とは?
async for
は、非同期イテレータ(asynchronous iterator) をループ処理するための構文です。
普通の for
との違いをまとめると、こんな感じです:
構文 | 対象 | 特徴 |
---|---|---|
for |
イテラブル/イテレータ | 同期処理 |
async for |
非同期イテレータ | 非同期処理(途中で await を挟める) |
たとえばチャットメッセージやAPIからのストリーミングデータのように、順に届く値を待ちながら処理するような場面で使われます。
🧠 非同期イテレータとは?
非同期イテレータは、以下の2つのメソッドを持ったオブジェクトのことです:
-
__aiter__(self)
非同期イテレータ本体を返す(=自分自身を返すことが多い) -
__anext__(self)
非同期で次の値を返す(終わったらStopAsyncIteration
を送る)
これを満たすクラスを作れば、async for
で繰り返し処理ができるようになります。
🔧 非同期イテレータの例
1秒おきにカウントアップする非同期イテレータのコードの例です。
import asyncio
class AsyncCounter:
def __init__(self):
self.count = 0
def __aiter__(self):
return self
async def __anext__(self):
if self.count >= 3:
raise StopAsyncIteration
await asyncio.sleep(1)
self.count += 1
return self.count
📝 ポイント解説
-
__aiter__()
はasync for
に対応するために必要で、「このオブジェクトは非同期イテレータですよ」という目印です。 -
__anext__()
はawait
を含めた非同期の「次の値を返す処理」です。 - 使い終わったら
StopAsyncIteration
を raise することでループ終了を伝えます。
💡 一般的に、イテレータは関数よりもクラスで作ることが多いです。
なぜなら__iter__
や__next__
/__anext__
などを定義しなければならないからです。
🔁 実際に async for で使ってみる
async def main():
async for number in AsyncCounter():
print(number)
asyncio.run(main())
✅ 実行結果(1秒ごとに出力)
1
2
3
非同期で 1 秒ずつ待って 1 → 2 → 3
と出力されました。
📌 async for を使う実務的な例
このような非同期イテレータは、次のような場面で使われることが多いです。
- WebSocket でチャットメッセージを順に受信する場合
(例:async for message in websocket:
) - ストリーミングAPIからリアルタイムでデータを取得する場合
- 非同期でファイルやログを読み取る処理
- 時間差で届くイベントを1つずつ処理する場合
🧠 まとめ
-
async for
は 非同期で値を順番に処理するための構文です - 使うには
__aiter__()
と__anext__()
を定義した 非同期イテレータ を用意する必要があります - 状態を持って処理を進めたいときは、クラスでイテレータを作るのが基本
- 実務では WebSocket やストリーミング処理などで使われています
非同期処理の世界は少しややこしく見えますが、少しずつ整理して使いどころを理解できるようになってきました。
この記事が、これから非同期処理を学ぶ誰かの助けにもなればうれしいです。