Pythonでコルーチンを使う(asyncio, Python 3.5以降)
この記事では、Pythonの非同期プログラミングにおけるコルーチンの使い方を解説します。asyncioライブラリを用いて、コルーチンを定義、実行し、並行処理を実現する方法を学びます。非同期処理の基本的な概念、awaitキーワード、asyncキーワード、タスクの管理方法などを具体的なコード例と共に説明します。
目次
コルーチンの基本
コルーチンは、一時停止可能な関数です。`async def`で定義します。`await`キーワードを使って、他のコルーチンの実行を待ちます。
import asyncio
async def my_coroutine():
print('コルーチン開始')
await asyncio.sleep(1) # 1秒待つ
print('コルーチン終了')
async def main():
await my_coroutine()
asyncio.run(main())
この例では、`my_coroutine`関数は1秒間一時停止し、その後終了します。`asyncio.run()`は、コルーチンを実行するための関数です。
asyncとawaitキーワード
`async`キーワードは、関数をコルーチンとして定義するために使用します。`await`キーワードは、コルーチンの実行が完了するまで待機するために使用します。
import asyncio
async def task1():
print('task1開始')
await asyncio.sleep(2)
print('task1終了')
return 'task1の結果'
async def task2():
print('task2開始')
await asyncio.sleep(1)
print('task2終了')
return 'task2の結果'
async def main():
result1 = await task1()
result2 = await task2()
print(f'task1の結果: {result1}')
print(f'task2の結果: {result2}')
asyncio.run(main())
asyncio.run()関数
`asyncio.run()`関数は、イベントループを作成し、コルーチンを実行します。Python 3.7以降で使用可能です。
import asyncio
async def my_coroutine():
print('Hello')
await asyncio.sleep(1)
print('World')
asyncio.run(my_coroutine())
タスクの並列実行
複数のタスクを並列に実行するには、`asyncio.gather()`関数を使用します。
import asyncio
async def task(name, delay):
await asyncio.sleep(delay)
print(f'{name}: 完了')
return f'{name}の結果'
async def main():
results = await asyncio.gather(
task('A', 2),
task('B', 1),
task('C', 3)
)
print(f'結果: {results}')
asyncio.run(main())
gather関数による同時実行
`asyncio.gather()`は複数のタスクを同時に実行し、それぞれの結果をリストで返します。
import asyncio
async def my_coroutine(i):
await asyncio.sleep(1)
return i * 2
async def main():
results = await asyncio.gather(my_coroutine(1), my_coroutine(2), my_coroutine(3))
print(results) # 出力:[2, 4, 6]
asyncio.run(main())
エラー処理
try-exceptブロックを使って、コルーチン内で発生した例外を処理できます。
import asyncio
async def my_coroutine():
try:
await asyncio.sleep(1)
raise Exception('エラー発生')
except Exception as e:
print(f'エラーキャッチ: {e}')
asyncio.run(my_coroutine())
実践例:複数のWebサイトからデータ取得
複数のWebサイトからデータを取得する例です。aiohttpライブラリが必要です。`pip install aiohttp`でインストールしてください。(aiohttpは2023年11月時点での最新版を使用してください)
import asyncio
import aiohttp
async def fetch_url(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
urls = ['https://www.example.com', 'https://www.google.com']
async with aiohttp.ClientSession() as session:
results = await asyncio.gather(*[fetch_url(session, url) for url in urls])
for result in results:
print(result[:100]) # 先頭100文字表示
asyncio.run(main())