C
Python/非同期/Lesson 21

非同期プログラミング入門

1時間·theory
Python

非同期プログラミング入門

🎯 このlessonを読んだら

このlessonを読み終えると、以下の3つのことに自信を持てるようになります。

  • ✅ Pythonがなぜ AI/データの標準言語になったのか
  • ✅ Python 3.x 基準のvenv + requirements.txtのセットアップ
  • ✅ print / input / type / dir の4つの組み込み関数

学習目標をチェックリストとして持ち、すべてに答えられるようになったらlessonを閉じてください。

async/await — コード + 実行結果

async def + await = 複数タスクの並行処理 (シングルスレッド、IO待機の効率化)。HTTP・DBコールの標準。


1. 同期 vs 非同期 — 時間の差

python
import time

# ❌ 同期 — 順次実行 (合計 3秒)
def get():
    time.sleep(1)
    return "完了"

start = time.time()
results = [get() for _ in range(3)]
print(time.time() - start)        # 3.0秒
python
import asyncio

# ✅ 非同期 — 同時実行 (合計 1秒)
async def get():
    await asyncio.sleep(1)        # 待機中に他の作業が可能
    return "完了"

async def main():
    start = asyncio.get_event_loop().time()
    results = await asyncio.gather(
        get(), get(), get()
    )
    print(asyncio.get_event_loop().time() - start)    # 1.0秒

asyncio.run(main())

2. 主要キーワード

キーワード意味
async def非同期関数の定義
await非同期結果を待つ (その間に他のタスクを実行可能)
asyncio.run()メインエントリーポイント
asyncio.gather()複数タスクの並行実行

3. HTTPコール (実務)

python
import asyncio
import aiohttp           # pip install aiohttp

async def get(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    urls = ["https://example.com", "https://python.org"]
    async with aiohttp.ClientSession() as session:
        results = await asyncio.gather(*[get(session, u) for u in urls])
        for r in results:
            print(len(r))

asyncio.run(main())

4. よくある間違い

python
# ❌ async 関数をそのまま呼び出し — coroutine を返す (実行されない)
result = get()                   # <coroutine object>

# ✅ await が必須
result = await get()             # 実際に実行

# ❌ 同期 sleep — 他の作業ができない
time.sleep(1)

# ✅ 非同期 sleep
await asyncio.sleep(1)

一言まとめ

async def + await + asyncio.gather() — IO待機の多い箇所 (HTTP・DB) でN倍高速化。

💻 async/await の基本
import asyncio

# コルーチン定義
async def say_hello(name, delay):
    await asyncio.sleep(delay)  # 非同期待機
    print(f"Hello, {name}!")
    return f"Done: {name}"

# 順次実行 (合計 3秒)
async def sequential():
    await say_hello("A", 1)
    await say_hello("B", 1)
    await say_hello("C", 1)

# 同時実行 (合計 1秒)
async def concurrent():
    await asyncio.gather(
        say_hello("A", 1),
        say_hello("B", 1),
        say_hello("C", 1)
    )

# 実行
async def main():
    print("順次実行:")
    await sequential()
    
    print("\n同時実行:")
    await concurrent()

# メイン実行
asyncio.run(main())

# 同期 vs 非同期比較
# 同期: リクエスト1完了 → リクエスト2開始 → リクエスト2完了
# 非同期: リクエスト1開始 → リクエスト2開始 → 両方完了

💡 重要ポイント

1. async def: コルーチン関数の定義
2. await: コルーチンの実行を待機
3. asyncio.run(): イベントループの実行

⚠️ asyncio.run() の注意事項: すでに実行中のイベントループ (Jupyter Notebook、FastAPI内部など) の中でasyncio.run()を呼び出すとRuntimeErrorが発生します。そのような環境では、await コルーチン を直接使用するか、nest_asyncioライブラリを活用してください。

Pythonの非同期プログラミングはasyncioライブラリで実装します。async def でコルーチン関数を定義し、await で非同期処理を待機します。asyncio.gather() で複数のコルーチンを並行実行します。I/Oバウンドな処理 (HTTP、DB、ファイル) に効果的で、CPUバウンドにはmultiprocessingを使用してください。aiohttpとhttpxは非同期HTTPクライアントライブラリです。

🐍 実際に試してみよう — 非同期プログラミング入門

上記の概念を実際にコードで実行してみてください。値を変えながら動作を直接確認するのが最速の学習方法です。
✏️ Python 코드
📟 コンソール出力
▶ 実行ボタンを押してください
🐍 Pyodideで実際のPythonを実行 — 初回は読み込みに3〜5秒

🤖 AIへのリクエスト例

このlessonの概念を理解すると、AIに具体的に指示を出せるようになります。漠然とした「直して」ではなく、語彙を持ったリクエスト — それがトークン節約の出発点です。

  • 「この同期的なrequestsコールをasyncio + httpxで並列化して」
  • 「このasyncコードに例外処理 (asyncio.gather return_exceptions) を追加して」

なぜこれがトークンを減らすのか

概念を知らないままだと、AIの回答を受け取っても「それって何ですか?」とまた聞き直す必要があります。その「聞き直し」がトークンを消費します。概念を一度習得すれば、会話が一度で終わります

先に読むとよい概念: 型ヒント
次のおすすめ: pytest入門
非同期プログラミング入門 - Python