python 标准库 Futures

I could either watch it pappen,or be part of it!
孤独是困苦的;但可不要变得庸俗;因为这样,你就会发现到处都是一片沙漠。
 —叔本华 《要么庸俗,要么孤独》
这是模块asyncio的一部分。
源代码: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py
Future 对象用来链接 底层回调式代码 和高层异步/等待式代码。
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()用于测试。)封装了 obj 的- Task对象,如果 obj 是一个协程 (使用- iscoroutine()进行检测);在此情况下该协程将通过- ensure_future()加入执行计划。等待 obj 的- Task对象,如果 obj 是一个可等待对象(- inspect.isawaitable()用于测试)如果 obj 不是上述对象会引发一个- TypeError异常。重要 查看- create_task()函数,它是创建新任务的首选途径。在 3.5.1 版更改: 这个函数接受任意 awaitable 对象。
- asyncio.wrap_future(future, **, loop=None*)- 将一个 - concurrent.futures.Future对象封装到- asyncio.Future对象中。
Future 对象
- class - asyncio.Future(**, loop=None*)- 一个 Future 代表一个异步运算的最终结果。线程不安全。 - Future 是一个 awaitable 对象。协程可以等待 Future 对象直到它们有结果或异常集合或被取消。 - 通常 Future 用于支持底层回调式代码(例如在协议实现中使用asyncio transports) 与高层异步/等待式代码交互。 - 经验告诉我们永远不要面向用户的接口暴露 Future 对象,同时建议使用 - loop.create_future()来创建 Future 对象。这种方法可以让 Future 对象使用其它的事件循环实现,它可以注入自己的优化实现。- 在 3.7 版更改: 加入对 - contextvars模块的支持。- 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()设置了异常,那么它就是 完成 。
- cancelled()- 如果 Future 已 取消 则返回 - True这个方法通常在设置结果或异常前用来检查 Future 是否已 取消 。- 1 
 2- 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()给回调函数传递参数,例如:- 1 
 2
 3- # Call 'print("Future:", fut)' when "fut" is done. 
 fut.add_done_callback(
 functools.partial(print, "Future:"))
 
 
*在 3.7 版更改:* 加入键值类形参 *context*。请参阅 [**PEP 567**](https://www.python.org/dev/peps/pep-0567) 查看更多细节。 
- remove_done_callback(callback)- 从回调列表中移除 callback 。返回被移除的回调函数的数量,通常为1,除非一个回调函数被添加多次。 
- cancel()- 取消 Future 并调度回调函数。如果 Future 已经 完成 或 取消 ,返回 - False。否则将 Future 状态改为 取消 并在调度回调函数后返回- True。
- exception()- 返回 Future 已设置的异常。只有 Future 在 完成 时才返回异常(或者 - None,如果没有设置异常)。如果 Future 已 取消,方法会引发一个- CancelledError异常。如果 Future 还没 完成 ,这个方法会引发一个- InvalidStateError异常。
- get_loop()- 返回 Future 对象已绑定的事件循环。3.7 新版功能. - 这个例子创建一个 Future 对象,创建和调度一个异步任务去设置 Future 结果,然后等待其结果: - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27- 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()函数。
 
        