この記事では、Pythonのコルーチンにおける「ネスト(入れ子)」と「コンポジション」に焦点を当てます。具体的なコード例とその解説、応用例を含めて解説を進めていきます。
目次
コルーチンとは?
コルーチンは、一時停止と再開が可能な特殊な関数です。ジェネレータを一般化したものとも言われます。通常の関数が一度呼び出されると最後まで処理が進むのに対し、コルーチンは途中で一時停止し、後から再開することができます。
ネストとコンポジションの基本
ネスト(Nested Coroutines)
ネストとは、一つのコルーチンの中で別のコルーチンを呼び出すことです。
# コルーチンのネスト例
async def coro1():
print("coro1: start")
await coro2() # coro2を呼び出す
print("coro1: end")
async def coro2():
print("coro2: called")
コンポジション(Coroutine Composition)
複数のコルーチンを組み合わせて一つのタスクを構成することを指します。
# コンポジション例
async def main():
task1 = asyncio.create_task(coro1())
task2 = asyncio.create_task(coro2())
await task1
await task2
コルーチンのネスト:詳細解説
yield fromの使用
Python 3.3以前では、ジェネレータベースのコルーチンでは`yield from`を使ってネストを行います。
# yield fromの使用例
def coro1():
yield "coro1: start"
yield from coro2()
yield "coro1: end"
def coro2():
yield "coro2: called"
yield fromの挙動
`yield from`は内部のコルーチン(coro2)が終了するまで、外部のコルーチン(coro1)を一時停止させます。
応用例1:非同期I/O処理
非同期I/O処理でファイルの読み書きを行いましょう。
import asyncio
async def read_file(file_path):
print(f"Reading {file_path}")
await asyncio.sleep(1)
print(f"Read {file_path}")
async def write_file(file_path):
print(f"Writing {file_path}")
await asyncio.sleep(1)
print(f"Wrote {file_path}")
async def io_tasks():
await asyncio.gather(read_file("file1.txt"), write_file("file2.txt"))
応用例2:複数APIへの非同期リクエスト
複数のAPIエンドポイントに非同期でリクエストを送信します。
import aiohttp
import asyncio
async def fetch_url(session, url):
async with session.get(url) as response:
return await response.text()
async def multiple_requests():
async with aiohttp.ClientSession() as session:
tasks = [fetch_url(session, f"https://api.example.com/data/{i}") for i in range(5)]
return await asyncio.gather(*tasks)
まとめ
Pythonのコルーチンにおけるネストとコンポジションについて、基本から応用までを解説しました。これらの概念を理解することで、非同期プログラミングの可能性が広がります。ぜひ実際のコードで試してみてください。
コメント