python - 正确使用 loop.create_future

标签 python python-asyncio concurrent.futures

我正在阅读 Python 文档和 PyMotW尝试学习 Async/Await、Futures 和 Tasks 的书。

Coroutines and Tasks documentation :

Normally there is no need to create Future objects at the application level code.

来自future documentation它声明如下:

loop.create_future()

Create an asyncio.Future object attached to the event loop.

This is the preferred way to create Futures in asyncio. This lets third-party event loops provide alternative implementations of the Future object (with better performance or instrumentation).

然而,在PyMotW chapter on Future ,作者创建了一个 future 对象,如下所示:

all_done = asyncio.Future()

我假设是因为这本书略微落后于当前版本的 Python。为了纠正这个问题,我做了以下事情:

future_Obj = event_loop.create_future()

所以作者的完整代码变成了:

import asyncio


def mark_done(future, result):
    print('setting future result to {!r}'.format(result))
    future.set_result(result)


event_loop = asyncio.get_event_loop()

try:

    future_Obj = event_loop.create_future()
    print('scheduling mark_done')
    event_loop.call_soon(mark_done, future_Obj, 'the result')

    print('entering event loop')
    result = event_loop.run_until_complete(future_Obj)
    print('returned result: {!r}'.format(result))
finally:
    print('closing event loop')
    event_loop.close()

print('future result: {!r}'.format(future_Obj.result()))

问题:

根据文档,上面示例中的 future_Obj = event_loop.create_future() 是创建 future 对象的正确方法吗?

最佳答案

Is future_Obj = event_loop.create_future() in the sample above, the correct way to create a future object according to the documentation?

是的,在所示的代码中,这正是实现它的方式。

需要注意的一件事是 future 与事件循环相关联,因此在顶层创建 future 会创建与循环相关的 future asyncio.get_event_loop()最初返回。一旦你切换到 asyncio.run ,你会得到一个错误,因为每次调用 asyncio.run创建一个新的事件循环。

为避免该问题,顶级 future 可以从 None 开始。并在协程内创建,使用 global作为适当的。由于您明确地传递了 future (这是一个值得遵循的好习惯),因此您根本不需要全局变量:

def mark_done(future, result):
    print('setting future result to {!r}'.format(result))
    future.set_result(result)

async def main():
    loop = asyncio.get_event_loop()
    future = loop.create_future()
    print('scheduling mark_done')
    loop.call_soon(mark_done, future, 'the result')
    print('suspending the coroutine')
    result = await future
    print('awaited result: {!r}'.format(result))
    print('future result: {!r}'.format(future.result()))
    return result

if __name__ == '__main__':
    print('entering the event loop')
    result = asyncio.run(main())
    print('returned result: {!r}'.format(result))

注意使用asyncio.run时,您永远不需要显式关闭循环,这是自动完成的。如果您使用的是 Python 3.6 或更早版本,您可以替换 asyncio.run(main())asyncio.get_event_loop().run_until_complete(main()) .

关于python - 正确使用 loop.create_future,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54273031/

相关文章:

python - 学习异步 : "coroutine was never awaited" warning error

python-3.x - 属性错误 : module 'concurrent' has no attribute 'futures' when I try parallel processing in python 3. 6

python - 列表的可变性,因为它与函数的参数相关

Python 3 List : How do I sort [ ('NJ' , 81), ('CA' , 81), ('DC' , 52)] 基于数字然后字母?

python - Aiohttp,异步 : RuntimeError: Event loop is closed

python - 子类化 future 类

python - 如何防止并发 future 库循环遍历先前迭代的项目?

python - 在 Python 3.5 的同一行中接受 3 个输入

python - 简单python代码上的mysqldump错误

python - 使用 asyncio 及时更新一些数据并通过 aiohttp 呈现?