Futures¶
原始碼:Lib/asyncio/futures.py、source:`Lib/asyncio/base_futures.py
Future 物件被用來連結低階回呼式程式和高階 async/await 程式。
Future 函式¶
- asyncio.isfuture(obj)¶
如果obj 為下面任意物件,回傳
True
:一個
asyncio.Future
的實例、一個
asyncio.Task
的實例、帶有
_asyncio_future_blocking
屬性的類 Future 物件 (Future-like object)。
在 3.5 版被加入.
- asyncio.ensure_future(obj,*,loop=None)¶
回傳:
obj 引數會保持原樣,obj 須為
Future
、Task
或類 Future 物件(可以用isfuture()
來進行檢查。)包裝 (wrap) 了obj 的
Task
物件,如果obj 是一個協程 (coroutine) (可以用iscoroutine()
來進行檢查);在此情況下該協程將透過ensure_future()
來排程。一個會等待obj 的
Task
物件,obj 須為一個可等待物件(inspect.isawaitable()
用於測試。)
如果obj 不是上述物件的話會引發一個
TypeError
例外。在 3.5.1 版的變更:這個函式接受任意awaitable 物件。
在 3.10 版之後被棄用:如果obj 不是類 Future 物件且loop 並未被指定,同時沒有正在執行的事件迴圈 (event loop),則會發出棄用警告。
- asyncio.wrap_future(future,*,loop=None)¶
將一個
concurrent.futures.Future
物件包裝到asyncio.Future
物件中。在 3.10 版之後被棄用:如果future 不是類 Future 物件且loop 未被指定,同時沒有正在執行的事件迴圈,則會發出棄用警告。
Future 物件¶
- classasyncio.Future(*,loop=None)¶
一個 Future 代表一個非同步運算的最終結果。並不支援執行緒安全 (thread-safe)。
Future 是一個awaitable 物件。協程可以等待 Future 物件直到它們有結果或例外被設置、或者被取消。一個 Future 可被多次等待而結果都會是相同的。
Future 通常用於讓低階基於回呼的程式(例如在協定實作中使用 asynciotransports)能夠與高階 async/await 程式互動。
經驗法則為永遠不要在提供給使用者的 API 中公開 Future 物件,同時建議使用
loop.create_future()
來建立 Future 物件。如此一來,不同實作的事件迴圈可以注入自己最佳化實作的 Future 物件。在 3.7 版的變更:加入對
contextvars
模組的支援。在 3.10 版之後被棄用:如果未指定loop 並且沒有正在執行的事件迴圈則會發出棄用警告。
- result()¶
回傳 Future 的結果。
如果 Future 狀態為done(完成),並擁有
set_result()
方法設定的一個結果,則回傳該結果之值。如果 Future 狀態為done,並擁有
set_exception()
方法設定的一個例外,那麼這個方法會引發該例外。如果 Future 已被cancelled(取消),此方法會引發一個
CancelledError
例外。如果 Future 的結果還不可用,此方法會引發一個
InvalidStateError
例外。
- set_result(result)¶
將 Future 標記為done 並設定其結果。
如果 Future 已經done 則引發一個
InvalidStateError
錯誤。
- set_exception(exception)¶
將 Future 標記為done 並設定一個例外。
如果 Future 已經done 則引發一個
InvalidStateError
錯誤。
- done()¶
如果 Future 已為done 則回傳
True
。如果 Future 有被cancelled、
set_result()
有被呼叫來為其設定結果、或set_exception()
有被呼叫為其設定例外,那麼它就是done。
- cancelled()¶
如果 Future 已經被cancelled 則回傳
True
。這個方法通常在為 Future 設定結果或例外前用來確認它還沒被cancelled:
ifnotfut.cancelled():fut.set_result(42)
- add_done_callback(callback,*,context=None)¶
新增一個在 Future 為done 時執行的回呼函式。
呼叫callback 並附帶做為唯一引數的 Future 物件。
如果呼叫這個方法時 Future 已經為done,回呼函式會被
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 已經是done 或cancelled,回傳
False
。否則將 Future 狀態改為cancelled 並在為回呼函式排程後回傳True
。在 3.9 版的變更:新增msg 參數。
- exception()¶
回傳被設定於此 Future 的例外。
只有 Future 在done 時才回傳例外(如果沒有設定例外則回傳
None
)。如果 Future 已被cancelled(取消),此方法會引發一個
CancelledError
例外。如果 Future 還不為done,此方法會引發一個
InvalidStateError
例外。
- get_loop()¶
回傳已被 Future 物件繫結 (bind) 的事件迴圈。
在 3.7 版被加入.
這個例子建立一個 Future 物件,建立一個非同步 Task 並為其排程以設定 Future 結果,然後等待 Future 結果出現:
asyncdefset_after(fut,delay,value):# Sleep for *delay* seconds.awaitasyncio.sleep(delay)# Set *value* as a result of *fut* Future.fut.set_result(value)asyncdefmain():# 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(awaitfut)asyncio.run(main())
重要
該 Future 物件是為了模仿concurrent.futures.Future
而設計。主要差異包含:
與 asyncio 的 Future 不同,
concurrent.futures.Future
實例不可被等待。asyncio.Future.result()
和asyncio.Future.exception()
不接受timeout 引數。Future 不為done 時
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()
無此引數。