Python での非同期プログラミングの実践的なガイド
Python asyncio の核となる概念を深く理解し、非同期プログラミングのベスト プラクティスを習得し、クローラーと IO 集約型タスクのパフォーマンスを向上させます。
非同期プログラミングの基礎
Python の asyncio モジュールは、async/await 構文を使用して、非同期コードを同期コードと同じように読み取れるようにする、同時実行コードを記述するためのインフラストラクチャを提供します。
中心となる概念
- イベント ループ: イベント ループ、非同期プログラムの実行エンジン
- Coroutine:
async defで定義された関数を使用するコルーチン - タスク: 同時スケジューリングに使用されるコルーチンのカプセル化であるタスク
- 将来: 将来の結果。未完了の操作を示します。
基本的な使い方
import asyncio
async def fetch_data(url: str) -> str:
"""模拟异步 HTTP 请求"""
await asyncio.sleep(1)
return f"Data from {url}"
async def main():
# 串行执行:耗时 3 秒
result1 = await fetch_data("https://api1.com")
result2 = await fetch_data("https://api2.com")
result3 = await fetch_data("https://api3.com")
# 并发执行:耗时 1 秒
results = await asyncio.gather(
fetch_data("https://api1.com"),
fetch_data("https://api2.com"),
fetch_data("https://api3.com"),
)
asyncio.run(main())
同時実行制御: セマフォ
同時実行数を制限する必要がある場合は、「asyncio.Semaphore」が最適な選択です。
async def crawl_with_limit(urls: list[str], limit: int = 10):
semaphore = asyncio.Semaphore(limit)
async def fetch(url: str):
async with semaphore:
return await fetch_data(url)
tasks = [fetch(url) for url in urls]
return await asyncio.gather(*tasks)
実際の応用
非同期プログラミングは、次のシナリオで特に役立ちます。
- Web クローラー: 大量の同時 HTTP リクエスト
- API 呼び出し: 複数の外部サービスを集約する
- ファイル IO: 多数のファイル読み取りおよび書き込み操作
- データベース クエリ: 複数のクエリを同時に実行します。
ヒント: すべてのシナリオが非同期の CPU 集中型タスクに適しているわけではなく、マルチプロセスを使用する必要があります。
要約する
Python で非同期プログラミングをマスターすると、IO 集約型アプリケーションのパフォーマンスを大幅に向上させることができます。重要なのは、イベント ループがどのように動作するかを理解し、セマフォを適切に使用して同時実行を制御し、適切な同時実行モードを選択することです。