8.13. ループ制御¶
ほとんどの asyncio スクリプトは、イベントループに直接触れることはありません。asyncio.run() で十分です。このページでは、そうでないケース(例外ハンドラのインストール、run とは異なるライフサイクルでのループの実行、計測のためにループオブジェクトを保持する場合)のための Loop のインターフェースを取り上げます。
8.13.1. ループの取得¶
asyncio.get_event_loop()--Loopオブジェクトを返します。コルーチンの内側からでも外側からでも安全に呼び出せます。asyncio.new_event_loop()-- MicroPython では、新しいループを作成するのではなく、既存のループの状態をリセット します。繰り返しておく価値のある注意点として、プログラムごとにイベントループはちょうど 1 つだけです。
Loop のメソッドと asyncio.run() 以外に、ループを 実行する ための API はありません。
8.13.2. ループを直接実行する¶
asyncio.run() は、ほぼすべてのアプリケーションにとって適切なエントリポイントです。そうでないケースのために、2 つの Loop メソッドが用意されています。
run_until_complete()-- awaitable を渡すと、その awaitable が完了するまでループを実行し、その結果を返します。1 回のasyncio.run()呼び出しから、ループの後始末を省いたものに相当します。run_forever()-- タスクの内側からstop()が呼び出されるまでループを実行します。トップレベルの awaitable はありません。アプリケーションはrun_foreverを呼び出す前に、必要なものをasyncio.create_task()でスケジュールしておくことが期待されます。
対になるメソッドは stop()(現在のタスクが完了した後にループを停止するよう要求する)と close()(ループのリソースを解放する)です。
8.13.3. ループ側でのタスク生成¶
create_task()--asyncio.create_task()と同じ操作です。一般的なケースでアプリケーションコードがループの参照を必要としなくて済むように、独立した関数が存在します。一方、すでにループ参照を持っている計測のために、メソッドが存在します。
8.13.4. 例外ハンドラ¶
コルーチンの呼び出しチェーン内のどこでも捕捉されなかった例外をタスクが送出すると、ループはハンドラを呼び出します。典型的なケースは、アプリケーションが asyncio.create_task() で作成し、一度も await しなかったタスクです。既定のハンドラは sys.stderr 経由でトレースバックを表示します。例外 のページでは、それをカスタムなものに差し替える方法を示しました。
set_exception_handler()-- カスタムハンドラをインストールします。ハンドラは呼び出し可能なhandler(loop, context)で、contextは少なくとも'message'を含み、通常は'exception'と'future'も含む辞書です。get_exception_handler()-- 現在インストールされているハンドラを返します。既定のものが使われている場合はNoneを返します。default_exception_handler()-- 組み込みのハンドラです。既定の動作 も 実行したいカスタムハンドラの内部で役立ちます(たとえば、フラッシュにログを記録 しつつ トレースバックを表示する場合)。call_exception_handler()-- 手動で構築したコンテキスト辞書を使って、現在インストールされているハンドラを実行します。主にループ自体が使うもので、アプリケーションが必要とすることはまれです。