Futures

原始碼: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py


Future 物件用於將底層基於回撥的程式碼與高層 async/await 程式碼橋接起來。

Future 函式

asyncio.isfuture(obj)

如果 obj 是以下任一情況,則返回 True

3.5 版本中新增。

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

返回

  • 如果 objFutureTask 或類 Future 物件,則按原樣返回 obj(使用 isfuture() 進行測試。)

  • 如果 obj 是協程(使用 iscoroutine() 進行測試),則返回包裝 objTask 物件;在這種情況下,協程將由 ensure_future() 排程。

  • 如果 obj 是可等待物件(使用 inspect.isawaitable() 進行測試),則返回將等待 objTask 物件。

如果 obj 不是上述任何一種情況,則會引發 TypeError

重要

另請參閱 create_task() 函式,它是建立新 Task 的首選方式。

儲存此函式結果的引用,以避免任務在執行過程中消失。

在 3.5.1 版本中更改: 該函式接受任何 可等待 物件。

自 3.10 版本棄用: 如果 obj 不是類 Future 物件,並且未指定 loop,並且沒有正在執行的事件迴圈,則會發出棄用警告。

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

concurrent.futures.Future 物件包裝在 asyncio.Future 物件中。

自 3.10 版本棄用: 如果 future 不是類 Future 物件,並且未指定 loop,並且沒有正在執行的事件迴圈,則會發出棄用警告。

Future 物件

class asyncio.Future(*, loop=None)

Future 表示非同步操作的最終結果。非執行緒安全。

Future 是一個 可等待 物件。協程可以等待 Future 物件,直到它們有結果或設定了異常,或者直到它們被取消。一個 Future 可以被多次等待,並且結果是相同的。

通常,Futures 用於使底層基於回撥的程式碼(例如,在使用 asyncio 傳輸 實現的協議中)與高層 async/await 程式碼進行互動操作。

經驗法則是永遠不要在面向使用者的 API 中公開 Future 物件,而建立 Future 物件的推薦方法是呼叫 loop.create_future()。這樣,替代事件迴圈實現可以注入其自身最佳化的 Future 物件實現。

在 3.7 版本中更改: 添加了對 contextvars 模組的支援。

自 3.10 版本棄用: 如果未指定 loop 並且沒有正在執行的事件迴圈,則會發出棄用警告。

result()

返回 Future 的結果。

如果 Future 已完成,並且具有透過 set_result() 方法設定的結果,則返回結果值。

如果 Future 已完成,並且具有透過 set_exception() 方法設定的異常,則此方法會引發該異常。

如果 Future 已被取消,則此方法會引發 CancelledError 異常。

如果 Future 的結果尚未可用,則此方法會引發 InvalidStateError 異常。

set_result(result)

將 Future 標記為完成並設定其結果。

如果 Future 已經完成,則引發 InvalidStateError 錯誤。

set_exception(exception)

將 Future 標記為完成並設定異常。

如果 Future 已經完成,則引發 InvalidStateError 錯誤。

done()

如果 Future 已完成,則返回 True

如果 Future 被取消,或者透過 set_result()set_exception() 呼叫設定了結果或異常,則 Future 已完成

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 已經 donecancelled,則返回 False。 否則,將 Future 的狀態更改為 cancelled,排程回撥,並返回 True

在 3.9 版本中更改: 添加了 msg 引數。

exception()

返回在此 Future 上設定的異常。

只有當 Future 為 done 時,才會返回異常(如果沒有設定異常,則返回 None)。

如果 Future 已被取消,則此方法會引發 CancelledError 異常。

如果 Future 尚未 done,此方法會引發 InvalidStateError 異常。

get_loop()

返回 Future 物件繫結的事件迴圈。

在 3.7 版本中新增。

此示例建立一個 Future 物件,建立並排程一個非同步 Task 來為 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。主要區別包括