Python 带有同步设置的异步函数

Python 带有同步设置的异步函数,python,python-3.x,asynchronous,async-await,python-asyncio,Python,Python 3.x,Asynchronous,Async Await,Python Asyncio,我不熟悉异步编程 我的理解是,它对于并行运行但涉及大量等待的任务非常有用。例如,下载10个zip存档并解压缩它们可以并行完成,但由于“下载”部分只是等待CPU的时间,因此异步IO在这里是一个有用的概念。如果我错了,请纠正我 我看到的所有教程都遵循上述类似的示例问题,并通过创建一组可等待项来解决它,然后一起等待它们。(例如,通过收集) 然而,对我来说,启动这样一个异步操作似乎是一个常见的要求,例如下载一个文件,继续并行地执行其他工作,直到实际需要该文件,然后检索它。这基本上就是“未来”所代表的 不

我不熟悉异步编程

我的理解是,它对于并行运行但涉及大量等待的任务非常有用。例如,下载10个zip存档并解压缩它们可以并行完成,但由于“下载”部分只是等待CPU的时间,因此异步IO在这里是一个有用的概念。如果我错了,请纠正我

我看到的所有教程都遵循上述类似的示例问题,并通过创建一组可等待项来解决它,然后一起等待它们。(例如,通过
收集

然而,对我来说,启动这样一个异步操作似乎是一个常见的要求,例如下载一个文件,继续并行地执行其他工作,直到实际需要该文件,然后检索它。这基本上就是“未来”所代表的

不过,我不知道如何用异步函数实现这一点。如果我不“等待”调用
download\u file
,那么它甚至不会执行初始设置,下载也不会启动。如果我立即“等待”电话,它将等待整个下载完成,我将无法并行完成任何工作。 我想出的唯一解决办法是让
下载\u文件
返回一个期待已久的未来。这真的是最好的方法吗?如果是这样的话,如果我们仍然必须像引入“async”关键字之前那样使用futures这样的对象,那么异步的意义何在呢?

解决方案(在asyncio中)是使用以下内容:

download_task = asyncio.create_task(download_file(...))
... code continues executing ...
这会在“后台”中生成
download_file()
(因为asyncio是单线程的,所以后台中没有真正的内容,所以请使用短引号)。然后,您可以继续您的业务,通常是做其他事情,最重要的是,等待其他事情。当您需要完成下载时,请使用
wait download\u task
获得结果

我想出的唯一解决办法是让
下载\u文件
返回一个期待已久的未来

asyncio.create_task()
有效地将任何协同程序(异步定义)转换为可期待的未来

如果是这样的话,如果我们还必须像引入“async”关键字之前那样使用futures这样的对象,那么异步还有什么意义呢


关键是您有了协同程序:一个实现和组合这些未来的非常方便的工具。您可以编写一个函数,例如
download_file
代码,就好像它是普通的顺序代码一样,但它可以与一堆其他异步代码并行运行。

我认为多线程可能是您想要的。请尝试使用asyncio进行测试,并打印一些独特的内容,如“开始文件名”,在task/coroutine的顶部,然后是类似“stop filename”的内容和coroutine的底部,查看事件循环是否在等待完成时切换到不同的任务。类似于本问答中的玩具示例。