正确使用loop.create_futu循环

2024-04-20 11:53:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在阅读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的当前版本。为了纠正这一点,我做了以下几点:

^{pr2}$

因此,作者的完整代码变成:

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对象的正确方法吗?在


Tags: theto文档loopeventasyncioobjformat
1条回答
网友
1楼 · 发布于 2024-04-20 11:53:43

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将创建一个绑定到asyncio.get_event_loop()最初返回的循环的future。一旦您切换到^{},您将得到一个错误,因为每次调用asyncio.run都会创建一个新的事件循环。在

为了避免这个问题,一个顶级的未来可以从None开始,并在一个协程中创建,适当地使用global。而且,由于要显式地传递未来(这是一个很好的做法),因此根本不需要全局变量:

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时,您永远不需要显式地关闭循环,这是自动完成的。如果您使用的是python3.6或更早版本,可以将asyncio.run(main())替换为asyncio.get_event_loop().run_until_complete(main())。在

相关问题 更多 >