期货

源代码: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py


期货 对象用于将低级基于回调的代码与高级 async/await 代码桥接。

期货函数

asyncio.isfuture(obj)

如果 obj 是以下任一对象,则返回 True

在版本 3.5 中添加。

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

返回

  • obj 参数本身,如果 objFutureTask 或类似期货的对象(isfuture() 用于测试)。

  • 一个包装 objTask 对象,如果 obj 是协程(iscoroutine() 用于测试);在这种情况下,协程将由 ensure_future() 调度。

  • 一个 Task 对象,它将等待 obj,如果 obj 是可等待对象(inspect.isawaitable() 用于测试)。

如果 obj 不是上述任何一种,则会引发 TypeError

重要

另请参阅 create_task() 函数,它是创建新任务的首选方法。

保存对该函数结果的引用,以避免任务在执行过程中消失。

在版本 3.5.1 中更改: 该函数接受任何 可等待 对象。

自版本 3.10 起弃用: 如果 obj 不是类似期货的对象,并且未指定 loop 且没有正在运行的事件循环,则会发出弃用警告。

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

concurrent.futures.Future 对象包装在 asyncio.Future 对象中。

自版本 3.10 起弃用: 如果 future 不是类似期货的对象,并且未指定 loop 且没有正在运行的事件循环,则会发出弃用警告。

期货对象

class asyncio.Future(*, loop=None)

期货表示异步操作的最终结果。不是线程安全的。

期货是 可等待 对象。协程可以等待期货对象,直到它们具有结果或设置异常,或者直到它们被取消。期货可以被多次等待,结果相同。

通常,期货用于使低级基于回调的代码(例如,在使用 asyncio 传输 实现的协议中)能够与高级 async/await 代码互操作。

经验法则是永远不要在面向用户的 API 中公开期货对象,创建期货对象的推荐方法是调用 loop.create_future()。这样,替代事件循环实现就可以注入自己的优化后的期货对象实现。

在版本 3.7 中更改: 添加了对 contextvars 模块的支持。

自版本 3.10 起弃用: 如果未指定 loop 且没有正在运行的事件循环,则会发出弃用警告。

result()

返回期货的结果。

如果期货已完成并且通过 set_result() 方法设置了结果,则返回结果值。

如果期货已完成并且通过 set_exception() 方法设置了异常,则此方法会引发异常。

如果期货已被取消,则此方法会引发 CancelledError 异常。

如果期货的结果尚未可用,则此方法会引发 InvalidStateError 异常。

set_result(result)

将期货标记为完成并设置其结果。

如果期货已完成,则会引发 InvalidStateError 错误。

set_exception(exception)

将期货标记为完成并设置异常。

如果期货已完成,则会引发 InvalidStateError 错误。

done()

如果期货已完成,则返回 True

如果期货被取消,或者通过 set_result()set_exception() 调用设置了结果或异常,则期货已完成

cancelled()

如果期货被取消,则返回 True

该方法通常用于在为期货设置结果或异常之前检查它是否未被取消

if not fut.cancelled():
    fut.set_result(42)
add_done_callback(callback, *, context=None)

添加一个回调,在期货完成时运行。

callback 使用期货对象作为其唯一参数调用。

如果在调用此方法时期货已完成,则回调将使用 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,如果未设置异常)。

如果期货已被取消,则此方法会引发 CancelledError 异常。

如果 Future 尚未完成,则此方法会引发 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。主要区别包括