python - 正确使用 loop.create_future
问题描述
我正在阅读 Python 文档和PyMotW书籍,试图学习 Async/Await、Futures 和 Tasks。
通常不需要在应用程序级代码中创建 Future 对象。
从未来的文档中,它说明了以下内容:
loop.create_future()
创建一个附加到事件循环的 asyncio.Future 对象。
这是在 asyncio 中创建 Futures 的首选方式。这允许第三方事件循环提供 Future 对象的替代实现(具有更好的性能或检测)。
然而,在PyMotW 关于 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
解决方案
future_Obj = event_loop.create_future()
在上面的示例中,根据文档创建未来对象的正确方法是什么?
是的,在所示的代码中,这正是这样做的方法。
需要注意的一件事是未来与事件循环相关联,因此在顶层创建未来会创建与asyncio.get_event_loop()
最初返回的循环相关联的未来。一旦你切换到asyncio.run
,你会得到一个错误,因为每次调用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
,您永远不需要显式关闭循环,这是自动完成的。如果您使用的是 Python 3.6 或更早版本,则可以替换asyncio.run(main())
为asyncio.get_event_loop().run_until_complete(main())
.
推荐阅读
- javascript - 如何使用 TestCafe 访问应用程序操作?
- python - Python多条重复记录
- bash - EC2 用户数据未启动我的应用程序
- apache-kafka - 如何查看从某个 IP 地址连接的 kafka 客户端应用程序?
- swift - 将 CGImage 转换为 MTLTexture 而不进行预乘
- javascript - 我可以在悬停时使用 highcharts 列堆叠而不突出整个系列吗
- python - 如何通过使用python在csv文件中搜索字符串的第一个单词来打印整个字符串(在单元格中)
- java - 在复杂的 HashMap 中使用 StringJoiner
- python - OpenCV Videowriter 无法在 Ubuntu 16.04 上运行
- r - 如何在所有列中比较两行(由定义的条件选择)?