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 的なオブジェクト
バージョン 3.5 で追加.
- asyncio.ensure_future(obj, *, loop=None)¶
下記のいずれかを返します:
obj が
Future
オブジェクト、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 a
InvalidStateError
exception.
- set_result(result)¶
Future を 完了 とマークし、結果を設定します。
Raises a
InvalidStateError
error if the Future is already done.
- set_exception(exception)¶
Future を 完了 とマークし、例外を設定します。
Raises a
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 オブジェクトが束縛されているイベントループを返します。
バージョン 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
を模倣してデザインされました。両者の重要な違いは以下の通りです:
asyncio の Futures と異なり、
concurrent.futures.Future
インスタンスは待ち受けできません。asyncio.Future.result()
とasyncio.Future.exception()
は timeout 引数を取りません。asyncio.Future.result()
とasyncio.Future.exception()
は Future が 未完了 の場合にInvalidStateError
例外を送出します。asyncio.Future.add_done_callback()
メソッドによって登録されたコールバックは、即座に呼び出されません。代わりにコールバックはloop.call_soon()
によりスケジュールされます。asyncio の Future は
concurrent.futures.wait()
およびconcurrent.futures.as_completed()
との互換性がありません。asyncio.Future.cancel()
accepts an optionalmsg
argument, butconcurrent.futures.Future.cancel()
does not.