拡張¶
asyncio を拡張する主な方法は、独自の イベントループ クラスを書くことです。
asyncio には、この作業を簡単にするための補助機能があります。
注釈
サードパーティーが既存の asyncio コードを再利用する際は注意してください。 新しい Python バージョンでは、API の 内部的な 部分について後方互換性が失われる可能性があります。
独自のイベントループを書く¶
asyncio.AbstractEventLoop には非常に多くのメソッドが宣言されており、すべてを一から実装するのは大変な作業です。
asyncio.BaseEventLoop を継承すれば、多くの共通メソッドの実装をそのまま利用できます。
その代わり、サブクラスでは asyncio.BaseEventLoop に宣言されているものの実装されていない 非公開 メソッドを実装する必要があります。
例えば loop.create_connection() は、引数の検査と DNS によるアドレス解決を行い、サブクラスで実装すべき loop._make_socket_transport() を呼び出します。
_make_socket_transport() は文書化されておらず、内部 API とみなされます。
Future と Task の非公開コンストラクター¶
asyncio.Future と asyncio.Task は直接作成しないでください。
代わりに、それぞれに対応するファクトリー loop.create_future() と loop.create_task()、または asyncio.create_task() を使ってください。
ただし、サードパーティーの イベントループ は、複雑で高度に最適化されたコードを自前で実装せずに利用するために、組み込みの Future と Task の実装を 再利用 してもかまいません。
この目的のために、以下の 非公開 コンストラクターを紹介します。
- Future.__init__(*, loop=None)¶
組み込みの Future インスタンスを作成します。
loop は省略可能なイベントループのインスタンスです。
- Task.__init__(coro, *, loop=None, name=None, context=None)¶
組み込みの Task インスタンスを作成します。
loop は省略可能なイベントループのインスタンスです。 他の引数については
loop.create_task()を参照してください。バージョン 3.11 で変更: context 引数が追加されました。
タスクの生存期間の管理¶
サードパーティーのタスク実装では、asyncio.all_tasks() と asyncio.current_task() でタスクを取得できるように、次の関数を呼び出す必要があります。
- asyncio._register_task(task)¶
新しい task を asyncio が管理するタスクとして登録します。
タスクのコンストラクターから呼び出してください。
- asyncio._unregister_task(task)¶
asyncio の内部データ構造から task の登録を解除します。
タスクが終了する直前に呼び出してください。
- asyncio._enter_task(loop, task)¶
現在のタスクを、引数 task に切り替えます。
タスク内の コルーチン を部分的に実行する直前 (
coroutine.send()またはcoroutine.throw()の呼び出し直前) に呼び出してください。
- asyncio._leave_task(loop, task)¶
現在のタスクを task から
Noneに戻します。coroutine.send()またはcoroutine.throw()の実行直後に呼び出してください。