为什么我需要将 python 协程包装到任务中/何时使用任务或协程?

Pat*_*ins 3 python task async-await python-asyncio

在 Python 中,有3 种主要类型的可等待对象:协程、任务和期货。

我可以await是协程,也可以是tasks.

等待协程

import asyncio

async def nested():
    return 42

async def main():
    print(await nested())  # will print "42".

asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)

等待任务

import asyncio

async def nested():
    return 42

async def main():
    task = asyncio.create_task(nested())
    await task

asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)

首先将协程包装在任务中的价值是什么?看起来他们做同样的事情。

我什么时候需要使用任务与协程?

Sha*_*ain 7

协程只是一个在当前等待的上下文中运行的函数。它可以代表调用者(调用 的人await)将执行交给事件循环。想想一个允许暂停它的线程的函数。您可以从另一个调用一个协程,但它们仍然共享同一个线程。

另一方面,Task 会立即将单独的作业发布到事件循环中。任务本身就是该工作的句柄。你可能await是一个任务,但它可以在“并行”中很好地运行——在单线程上下文中,这意味着任务可以在其他 josb 产生时运行(例如等待 I/O)。任务可能在您调用之前完成await

没有任务的示例:

job_1 = sleep(5)
job_2 = sleep(2)

# will sleep for 5 seconds
await job_1

# will sleep for another 2 seconds
await job_2
Run Code Online (Sandbox Code Playgroud)

任务示例:

job_1 = sleep(5)
job_2 = asyncio.create_task(sleep(2))

# will sleep for 5 seconds
await job_1

# by this time, job_2 is complete
# because previous job has yielded at some point, allowing other jobs to run
# thus await takes no time
await job_2
Run Code Online (Sandbox Code Playgroud)