banner
kanes

kanes

小白でも理解できるPythonコルーチンとasyncioガイド

小白でも理解できる Python コルーチンと asyncio ガイド#

一、生活シーンから非同期プログラミングを理解する#

1.1 ミルクティーを買う 2 つの方法#

あなたが 3 杯のミルクティーを買うと仮定します。各杯の製作には 2 分かかります:

従来の方法(同期):

def ミルクティーを買う_同期():
    for _ in range(3):
        2分待つ()  # じっと待つ
        ミルクティーを受け取る()

# 総時間:3×2=6分 ❌

賢い方法(非同期):

async def ミルクティーを買う_非同期():
    注文リスト = [注文(), 注文(), 注文()]  # 同時に注文
    await asyncio.gather(*注文リスト)  # 待ちながらスマホをいじる

# 総時間:2分 ✅

1.2 コルーチンは配達員のようなもの#

配達員が同時に複数の注文を処理している様子を想像してください:

  • A 店で料理を受け取る(待っている間に B 店へ)
  • 途中で新しい注文を受ける(ルートを柔軟に調整)
  • 配達後すぐに次の注文を受ける(時間を無駄にしない)

これがコルーチンの働き方です!複数の配達員(スレッド)は必要なく、1 人で効率的にタスクを完了できます。


二、最も簡単なコルーチン入門(実行可能なコード付き)#

2.1 こんにちはコルーチン版#

import asyncio

async def 挨拶(name):  # 重要1:asyncでコルーチンを定義
    print(f"{name}が作業を始めます")
    await asyncio.sleep(1)  # 重要2:待機時に中断
    print(f"{name}の作業が完了しました")

async def 主タスク():
    await asyncio.gather(
        挨拶("小明"),
        挨拶("小紅")
    )

asyncio.run(主タスク())  # 重要3:イベントループを起動

出力結果:

小明が作業を始めます
小紅が作業を始めます
(1秒待機)
小明の作業が完了しました
小紅の作業が完了しました

2.2 実行プロセスの図解#

|700x615


三、必ず押さえておくべき 3 つのコア概念#

3.1 コルーチンの三要素#

要素説明類比
async defコルーチン関数を宣言配達注文に "急ぎ" ラベルを貼る
await一時停止して制御権を譲る配達員が他の注文を配達するために一時的に離れる
イベントループすべてのタスクのスケジューラー配達プラットフォームの配達システム

3.2 よくある誤解リスト#

  1. 誤り:通常の関数内で await を使用

    def 通常の関数():
        await asyncio.sleep(1)  # エラー!
    
  2. 誤り:タスクを作成するのを忘れる

    async def 誤った例():
        # 順次実行、並行性なし!
        await タスク1()
        await タスク2()
    
  3. 正しい方法:

    async def 正しい例():
        task1 = asyncio.create_task(タスク1())
        task2 = asyncio.create_task(タスク2())
        await task1
        await task2
    

四、手取り足取り実践:複数の画像をダウンロード#

4.1 同期バージョン(亀のような速度)#

import requests

def 画像をダウンロード(url):
    print(f"{url}のダウンロードを開始します")
    data = requests.get(url).content
    with open("画像.jpg", "wb") as f:
        f.write(data)
    print(f"{url}のダウンロードが完了しました")

def 主関数():
    urls = ["url1", "url2", "url3"]  # 3つの画像アドレスを仮定
    for url in urls:
        画像をダウンロード(url)

# 総時間:1枚あたりの時間 × 数量

4.2 非同期バージョン(飛ぶような感覚)#

import aiohttp

async def 非同期ダウンロード(url):
    async with aiohttp.ClientSession() as session:
        print(f"{url}のダウンロードを開始します")
        async with session.get(url) as response:
            data = await response.read()
        with open(f"{url.split('/')[-1]}", "wb") as f:
            f.write(data)
        print(f"{url}のダウンロードが完了しました")

async def 主タスク():
    urls = ["url1", "url2", "url3"]
    await asyncio.gather(*[非同期ダウンロード(url) for url in urls])

asyncio.run(主タスク())

4.3 パフォーマンス比較#

画像数同期時間非同期時間速度向上
1020 秒2 秒10 倍
100200 秒5 秒40 倍

五、よくある質問と回答#

Q1:コルーチンとマルチスレッドの違いは?#

特性コルーチンマルチスレッド
リソース使用1 つのスレッドで全てを処理各スレッドが独立したリソースを必要
切り替え方法自発的に制御権を譲るシステムによって強制的に切り替え
適用シーン大量の IO 操作に適して計算集約型タスクに適して
プログラミングの難易度非同期構文を理解する必要があるスレッドセーフの問題を扱う必要がある

Q2:いつコルーチンを使えないか?#

  • 大量の CPU 計算が必要なシーン(例:動画のエンコード)
  • 非同期をサポートしていないライブラリを使用する場合(例えば、従来のデータベースドライバ)
  • 複数のコアで並列計算が必要な場合(マルチプロセスと組み合わせる必要がある)

Q3:コルーチンプログラムをデバッグするには?#

  1. asyncio.run()をエントリーポイントとして使用

  2. コルーチン内で通常の print 文を使用

  3. 専門のデバッガを使用:

    import logging
    logging.basicConfig(level=logging.DEBUG)
    

六、最適な学習ルートの提案#

6.1 初心者の 3 ステップ#

  1. まず同期コードを書いてビジネスプロセスを理解する
  2. 時間のかかる操作を async/await に置き換える
  3. asyncio.gatherを使って並行性を実現する

6.2 おすすめの練習プロジェクト#

プロジェクトタイプ実現機能スキルポイント
天気クエリ複数の都市の天気を同時にクエリ基本的な非同期リクエスト
ウェブ監視複数のウェブサイトの状態を定期的にチェック非同期定期タスク
チャットボット複数のユーザーのメッセージを同時に処理並行メッセージ処理

七、この 5 つの文を覚えておけば大丈夫#

  1. async def:コルーチンのスタートライン
  2. await:IO に遭遇したら手を挙げて一時停止
  3. イベントループ:裏方の総スケジューラー
  4. create_task:コルーチンを実行可能なタスクに変える
  5. asyncio.run():プログラムの起動スイッチ

この記事は Mix Space によって xLog に同期更新されました
元のリンクは https://blog.kanes.top/posts/default/asyncio


読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。