Python异步等待 使用async和await关键字来创建和暂停协程

本文介绍了Python 协程以及如何使用 Pythonasyncawait关键字来创建和暂停协程。

Python协程介绍

协程是一种常规函数,能够在遇到可能需要一段时间才能完成的操作时暂停执行。

当长时间运行的操作完成时,可以恢复暂停的协程并执行该协程中的剩余代码。

当协程等待长时间运行的操作时,可以运行其他代码。通过这样做,可以异步运行程序以提高其性能。

要创建和暂停协程,可以使用 Pythonasyncawait关键字:

  • async关键字创建协程。
  • await关键字暂停协程。

使用 Python async 关键字定义协程

下面定义了一个返回整数平方数的简单函数:

def square(number: int) -> int:
return number*number

可以将一个整数传递给square()函数以获取其平方数:

def square(number: int) -> int:
return number*number
result = square(10)
print(result)

输出:

<span style="background-color:#f8f8f8"><span style="color:#212529"><code class="language-undefined">100</code></span></span>

当您将async关键字添加到函数时,该函数就变成了协程:

async def square(number: int) -> int:
return number*number

一个调用协程返回一个稍后运行的协程对象。例如:

async def square(number: int) -> int:
return number*number
result = square(10)
print(square)

输出:

<coroutine object square at 0x00000185C31E7D80>
sys:1: RuntimeWarning: coroutine 'square' was never awaited

在这个例子中,我们调用square()协程,将返回值赋值给result变量,并打印出来。

调用协程时,Python 不会立即执行协程中的代码。相反,它返回一个协程对象。

输出中的第二行还显示一条错误消息,指示从未等待协程。在以下await部分中有更多相关信息:

<span style="background-color:#f8f8f8"><span style="color:#212529"><code class="language-typescript"><span style="color:#6cb6ff">sys</span>:<span style="color:#6cb6ff">1</span>: <span style="color:#dcbdfb">RuntimeWarning</span>: coroutine <span style="color:#96d0ff">'square'</span> was <span style="color:#f69d50">never</span> awaited</code></span></span>

要运行协程,您需要在事件循环中执行它。在 Python 3.7 之前,您必须手动创建一个事件循环来执行协程并关闭事件循环。

但是,从 3.7 版本开始,该asyncio库添加了一些简化事件循环管理的函数。

例如,您可以使用asyncio.run()函数自动创建事件循环、运行协程并关闭它。

下面使用该asyncio.run()函数执行square()协程并得到结果:

import asyncio
async def square(number: int) -> int:
return number*number
result = asyncio.run(square(10))
print(result)

输出:

<span style="background-color:#f8f8f8"><span style="color:#212529"><code class="language-undefined">100</code></span></span>

请务必注意,asyncio.run()被设计为asyncio程序的主要入口点。

此外,该asyncio.run()函数仅执行一个协程,该协程可能会调用程序中的其他协程和函数。

使用 Python await 关键字暂停协程

关键字暂停协程的await执行。await关键字后跟对协程的调用,如下所示:

<span style="background-color:#f8f8f8"><span style="color:#212529"><code class="language-python">result = <span style="color:#f47067">await</span> my_coroutine()</code></span></span>

await关键字使执行my_coroutine(),等待代码完成,并返回结果。

重要的是要注意await关键字仅在协程内有效。换句话说,您必须await在协程中使用关键字。

这就是为什么您在上面的示例中看到在await协程外部使用关键字的错误消息的原因。

以下示例显示如何使用await关键字暂停协程:

import asyncio
async def square(number: int) -> int:
return number*number
async def main() -> None:
x = await square(10)
print(f'x={x}')
y = await square(5)
print(f'y={y}')
print(f'total={x+y}')
asyncio.run(main())

输出:

x=100
y=25
total=125

首先,square()使用await关键字调用协程。await关键字会暂停协程的执行,main()等待square()协程完成,并返回结果:

x = await square(10)
print(f'x={x}')

square()其次,使用await关键字第二次调用协程:

y = await square(5)
print(f'y={y}')

三、显示总数:

<span style="background-color:#f8f8f8"><span style="color:#212529"><code class="language-python"><span style="color:#f69d50">print</span>(<span style="color:#96d0ff">f'total=<span style="color:#adbac7">{x+y}</span>'</span>)</code></span></span>

以下语句使用该run()函数来执行main()协程并管理事件循环:

<span style="background-color:#f8f8f8"><span style="color:#212529"><code class="language-python">asyncio.run(main())</code></span></span>

到目前为止,我们的程序像同步程序一样执行。它没有揭示异步编程模型的强大功能。

总结

  • 协程是一种常规函数,具有暂停长时间运行的操作、等待结果并从暂停点恢复的能力。
  • 使用async关键字定义协程。
  • 使用await关键字暂停协程。
  • 使用asyncio.run()函数在事件循环上自动执行协程并管理事件循环。

猜你喜欢

转载自blog.csdn.net/qq_41221596/article/details/131616839