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 是一個可等待物件(使用
inspect.isawaitable()
進行測試),則返回一個將等待 obj 的Task
物件。
如果 obj 不屬於上述任何一種情況,則會引發
TypeError
。版本 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 可以被多次等待,結果是相同的。
通常,Future 用於使低階基於回撥的程式碼(例如在透過 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 已 完成 或已 取消,則返回
False
。否則,將 Future 的狀態更改為 取消,排程回撥,並返回True
。版本 3.9 中有改變: 添加了 msg 引數。
- exception()¶
返回在此 Future 上設定的異常。
只有當 Future 處於 完成 狀態時,才返回異常(如果沒有設定異常,則返回
None
)。如果 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 Future 不同,
concurrent.futures.Future
例項不能被等待。asyncio.Future.result()
和asyncio.Future.exception()
不接受 timeout 引數。當 Future 未 完成 時,
asyncio.Future.result()
和asyncio.Future.exception()
會引發InvalidStateError
異常。透過
asyncio.Future.add_done_callback()
註冊的回撥不會立即被呼叫。它們而是透過loop.call_soon()
排程。asyncio Future 不相容
concurrent.futures.wait()
和concurrent.futures.as_completed()
函式。asyncio.Future.cancel()
接受可選的msg
引數,而concurrent.futures.Future.cancel()
不接受。