期货 — Python 文档
期货
源代码: :source:`Lib/asyncio/futures.py`, :source:`Lib/asyncio/base_futures.py`
Future 对象用于桥接 低级基于回调的代码 与高级异步/等待代码。
未来功能
- asyncio.isfuture(obj)
如果 obj 是以下之一,则返回
True
:asyncio.Future 的实例,
asyncio.Task 的一个实例,
具有
_asyncio_future_blocking
属性的类似 Future 的对象。
3.5 版中的新功能。
- asyncio.ensure_future(obj, *, loop=None)
返回:
obj 参数原样,如果 obj 是 Future、Task 或类似 Future 的对象 (isfuture( ) 用于测试。)
一个 Task 对象包装 obj,如果 obj 是一个协程(iscoroutine() 用于测试); 在这种情况下,协程将由
ensure_future()
调度。如果 obj 是可等待的(inspect.isawaitable() 用于测试,则将在 obj 上等待的 Task 对象。 )
如果 obj 不是上述任何一个,则会引发 TypeError。
在 3.5.1 版更改: 该函数接受任何 awaitable 对象。
自 3.10 版起已弃用:如果 obj 不是类似 Future 的对象且未指定 loop 并且没有正在运行的事件循环,则会发出 弃用警告。
- asyncio.wrap_future(future, *, loop=None)
将 concurrent.futures.Future 对象包装在 asyncio.Future 对象中。
自 3.10 版起已弃用:如果 future 不是类似 Future 的对象并且未指定 loop 并且没有正在运行的事件循环,则会发出 弃用警告。
未来对象
- class asyncio.Future(*, loop=None)
Future 表示异步操作的最终结果。 不是线程安全的。
Future 是一个 awaitable 对象。 协程可以等待 Future 对象,直到它们有结果或异常集,或者直到它们被取消。
通常 Futures 用于启用基于回调的低级代码(例如 在使用 asyncio transsports) 实现的协议中,与高级异步/等待代码进行互操作。
经验法则是永远不要在面向用户的 API 中公开 Future 对象,创建 Future 对象的推荐方法是调用 loop.create_future()。 通过这种方式,替代事件循环实现可以注入自己优化的 Future 对象实现。
3.7 版更改: 添加了对 contextvars 模块的支持。
自 3.10 版起已弃用:如果未指定 loop 且没有正在运行的事件循环,则会发出 弃用警告。
- result()
返回 Future 的结果。
如果 Future 是 done 并且具有由 set_result() 方法设置的结果,则返回结果值。
如果 Future 是 done 并且有一个由 set_exception() 方法设置的异常,这个方法会引发异常。
如果 Future 已被 取消 ,则此方法会引发 CancelledError 异常。
如果 Future 的结果尚不可用,则此方法会引发 InvalidStateError 异常。
- set_result(result)
将 Future 标记为 done 并设置其结果。
如果 Future 已经 done,则引发 InvalidStateError 错误。
- set_exception(exception)
将 Future 标记为 done 并设置例外。
如果 Future 已经 done,则引发 InvalidStateError 错误。
- done()
如果 Future 是 done,则返回
True
。一个 Future 是 done 如果它被 取消 或者如果它有结果或异常设置 set_result() 或 set_exception()调用。
- cancelled()
如果 Future 被 取消 ,则返回
True
。该方法通常用于在设置结果或异常之前检查 Future 是否未 取消 :
if not fut.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 或 canceled,则返回
False
。 否则,将 Future 的状态更改为 cancelled,安排回调,并返回True
。3.9 版本变化: 增加了
msg
参数。
- exception()
返回在此 Future 上设置的异常。
仅当 Future 为 done 时才返回异常(或
None
如果未设置异常)。如果 Future 已被 取消 ,则此方法会引发 CancelledError 异常。
如果 Future 还没有 done,这个方法会引发一个 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 没有 done 时引发 InvalidStateError 异常。
- 使用 asyncio.Future.add_done_callback() 注册的回调不会立即调用。 它们被安排为 loop.call_soon()。
- asyncio Future 与 concurrent.futures.wait() 和 concurrent.futures.as_completed() 函数不兼容。
- asyncio.Future.cancel() 接受可选的
msg
参数,但concurrent.futures.cancel()
不接受。