Future

ソースコード: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py


Future オブジェクトは 低水準のコールバックベースのコード と高水準の async/await コードとの間を橋渡しします。

Future の関数

asyncio.isfuture(obj)

オブジェクト obj が下記のいずれかであれば True を返します:

  • asyncio.Future クラスのインスタンス

  • asyncio.Task クラスのインスタンス

  • _asyncio_future_blocking 属性を持った Future 的なオブジェクト

Added in version 3.5.

asyncio.ensure_future(obj, *, loop=None)

下記のいずれかを返します:

  • objFuture オブジェクト、 Task オブジェクト、または Future 的なオブジェクト (isfuture() 関数を使って検査します) である場合には obj そのもの

  • 引数 obj がコルーチンである (iscoroutine() 関数を使って検査します) 場合には obj をラップした Task オブジェクト; この場合コルーチンは ensure_future() によりスケジュールされます。

  • 引数 obj が awaitable である (inspect.isawaitable() 関数を使って検査します) 場合には obj を await する Task オブジェクト

引数 obj が上記のいずれにもあてはまらない場合は TypeError 例外を送出します。

重要

Task を生成するより好ましい方法である create_task() 関数も参照してください。

Save a reference to the result of this function, to avoid a task disappearing mid-execution.

バージョン 3.5.1 で変更: この関数はどんな awaitable なオブジェクトでも受け入れるようになりました。

バージョン 3.10 で非推奨: Deprecation warning is emitted if obj is not a Future-like object and loop is not specified and there is no running event loop.

asyncio.wrap_future(future, *, loop=None)

concurrent.futures.Future オブジェクトを asyncio.Future オブジェクトでラップします。

バージョン 3.10 で非推奨: Deprecation warning is emitted if future is not a Future-like object and loop is not specified and there is no running event loop.

Future オブジェクト

class asyncio.Future(*, loop=None)

Future は非同期処理の最終結果を表すクラスです。スレッドセーフではありません。

Future is an awaitable object. Coroutines can await on Future objects until they either have a result or an exception set, or until they are cancelled. A Future can be awaited multiple times and the result is same.

典型的には、 Future は低水準のコールバックベースのコード (たとえば asyncio の transports を使って実装されたプロトコル) が高水準の async/await と相互運用することを可能にするために利用されます。

経験則は Future オブジェクトをユーザー向けの API であらわに利用しないことです。推奨される Future オブジェクトの生成方法は loop.create_future() を呼び出すことです。これによりイベントループの代替実装は、自身に最適化された Future オブジェクトの実装を合わせて提供することができます。

バージョン 3.7 で変更: contextvars モジュールのサポートを追加。

バージョン 3.10 で非推奨: Deprecation warning is emitted if loop is not specified and there is no running event loop.

result()

Future の結果を返します。

Future が 完了 していて、 set_result() メソッドにより設定された結果を持っている場合は結果の値を返します。

Future が 完了 していて、 set_exception() メソッドにより設定された例外を持っている場合はその例外を送出します。

Future が キャンセルされた 場合、このメソッドは CancelledError 例外を送出します。

If the Future's result isn't yet available, this method raises an InvalidStateError exception.

set_result(result)

Future を 完了 とマークし、結果を設定します。

Raises an InvalidStateError error if the Future is already done.

set_exception(exception)

Future を 完了 とマークし、例外を設定します。

Raises an InvalidStateError error if the Future is already done.

done()

Future が 完了 しているなら True を返します。

Future は キャンセルされた か、または set_result() メソッドや set_exception() メソッドの呼び出しにより結果や例外が設定された場合に 完了 とみなされます。

cancelled()

Future が キャンセルされた 場合に True を返します。

通常の場合、このメソッドは Future に処理結果や例外を設定する前に Future が キャンセルされていない ことを確認するために使用されます:

if not fut.cancelled():
    fut.set_result(42)
add_done_callback(callback, *, context=None)

Future が 完了 したときに実行されるコールバックを追加します。

callback は Future オブジェクトだけを引数にとって呼び出されます。

このメソッドが呼び出される時点ですでに Future が 完了 している場合、コールバックは loop.call_soon() メソッドによりスケジュールされます。

オプションのキーワード引数 context を使って、コールバック*callback* を実行する際のコンテキスト contextvars.Context を設定することができます。コンテキスト context が指定されない場合は現在のコンテキストが使われます。

コールバックにパラメータを渡すには、次の例のように functools.partial() を使うことができます:

# Call 'print("Future:", fut)' when "fut" is done.
fut.add_done_callback(
    functools.partial(print, "Future:"))

バージョン 3.7 で変更: キーワード引数 context が追加されました。詳細は PEP 567 を参照してください。

remove_done_callback(callback)

コールバックリストから callback を削除します。

削除されたコールバックの数を返します。コールバックが複数回追加されていない限り、通常は1が返ります。

cancel(msg=None)

Future をキャンセルし、コールバックをスケジュールします。

Future がすでに 完了 または キャンセル された場合、 False を返します。そうでない場合 Future の状態を キャンセル に変更した上でコールバックをスケジュールし、 True を返します。

バージョン 3.9 で変更: Added the msg parameter.

exception()

この Future オブジェクトに設定された例外を返します。

例外 (または例外が設定されていないときは None) は Future が 完了 している場合のみ返されます。

Future が キャンセルされた 場合、このメソッドは CancelledError 例外を送出します。

Future が 未完了 の場合、このメソッドは InvalidStateError 例外を送出します。

get_loop()

Future オブジェクトが束縛されているイベントループを返します。

Added in version 3.7.

この例は Future オブジェクトを生成し、Future に結果を設定するための非同期タスクを生成してスケジュールし、そして Future に結果が設定されるまで待機します:

async def set_after(fut, delay, value):
    # Sleep for *delay* seconds.
    await asyncio.sleep(delay)

    # Set *value* as a result of *fut* Future.
    fut.set_result(value)

async def main():
    # Get the current event loop.
    loop = asyncio.get_running_loop()

    # Create a new Future object.
    fut = loop.create_future()

    # Run "set_after()" coroutine in a parallel Task.
    # We are using the low-level "loop.create_task()" API here because
    # we already have a reference to the event loop at hand.
    # Otherwise we could have just used "asyncio.create_task()".
    loop.create_task(
        set_after(fut, 1, '... world'))

    print('hello ...')

    # Wait until *fut* has a result (1 second) and print it.
    print(await fut)

asyncio.run(main())

重要

Future オブジェクトは concurrent.futures.Future を模倣してデザインされました。両者の重要な違いは以下の通りです: