ZetCode

Python async/await

最后修改于 2024 年 1 月 29 日

在本文中,我们将展示如何在 Python 中使用 async/await 关键字。

通过异步编程,我们可以与主程序执行并发地执行任务。async 和 await 关键字简化了 Python 中的异步编程。Python 在语言中内置了异步编程模型。

Python 协程

协程是用于协作式多任务处理的 Python 函数,它们可以被暂停和恢复。协程使用 async def 语法声明。

async/await 关键字

async/await 关键字在 Python 3.7 中标准化。它们简化了 Python 中的异步编程。async 关键字用于创建 Python 协程。await 关键字会挂起协程的执行,直到它完成并返回结果数据。await 关键字只能在 async 函数内部工作。

Python async/await 示例一

以下是一个使用 async/await 关键字的简单程序。

simple.py
#!/usr/bin/python

import asyncio

async def mul(x, y):
    return x * y

loop = asyncio.get_event_loop()

res = loop.run_until_complete(mul(5, 5))
print(res2)

loop.close()

该程序创建并运行一个异步函数。

async def mul(x, y):
    return x * y

协程是使用 async 修饰符声明的函数。

loop = asyncio.get_event_loop()

get_event_loop 返回一个 asyncio 事件循环。执行异步代码需要事件循环。

res = loop.run_until_complete(mul(5, 5))

run_until_complete 函数运行事件循环直到一个 future 完成。它返回 future 的结果,或者抛出异常。Future 代表异步操作的最终结果。

Python async/await 示例二

使用 asyncio.run,我们可以简化代码。该函数创建一个事件循环,调度协程,并在最后关闭事件循环。

simple2.py
#!/usr/bin/python

import asyncio

async def add(x, y):
    return x + y

async def get_results():
    res1 = await add(3, 4)
    res2 = await add(8, 5)

    print(res1, res2)

asyncio.run(get_results())

在这个示例中,我们运行了两个异步函数。

$ python simple2.py 
7 13

Python async/await 示例三

Gathering 是一种方便的方式,可以安排多个协程并发运行。我们使用 asyncio.gather 来收集协程。

使用 asyncio.sleep,我们可以创建一个在指定秒数后完成的协程。它经常用于模拟长时间运行的任务。

simple3.py
#!/usr/bin/python

import asyncio
import time
import random

async def task1():

    wait = random.randint(0, 3)
    await asyncio.sleep(wait)
    print("task 1 finished")


async def task2():

    wait = random.randint(0, 3)
    await asyncio.sleep(wait)
    print("task 2 finished")


async def task3():

    wait = random.randint(0, 3)
    await asyncio.sleep(wait)
    print("task 3 finished")


async def main():

    for x in range(2):
        await asyncio.gather(task1(), task2(), task3())
        time.sleep(1)
        print('----------------------------')

t1 = time.perf_counter()
asyncio.run(main())
t2 = time.perf_counter()

print(f'Total time elapsed: {t2-t1:0.2f} seconds')

我们有三个任务,它们在随机秒数内完成。这样我们就模拟了三个不同的长时间运行任务的执行。

async def main():

    for x in range(2):
        await asyncio.gather(task1(), task2(), task3())
        print('----------------------------')

主函数收集所有三个任务。它也是一个协程,用 async 装饰。我们使用 await 关键字等待 asyncio.gather 的结果。

$ python simple3.py 
task 2 finished
task 1 finished
task 3 finished
----------------------------
task 3 finished
task 2 finished
task 1 finished
----------------------------
Total time elapsed: 8.01 seconds

Python Playwright 异步示例

许多库都支持异步编程。MS Playwright 库允许以同步和异步模式自动化浏览器。

screenshot.py
#!/usr/bin/python

import asyncio

from playwright.async_api import async_playwright

async def main():

    async with async_playwright() as playwright:

        webkit = playwright.webkit
        browser = await webkit.launch()
        page = await browser.new_page()

        url = 'http://webcode.me'
        await page.goto(url)
        await page.screenshot(path='shot.png')

        await browser.close()

asyncio.run(main())

在这个示例中,我们使用 Playwright 创建了一个网页的截图。我们使用了 async API。

来源

Python asyncio - 语言参考

在本文中,我们处理了 Python 中的 async/await 关键字。

作者

我叫 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教学编程方面拥有十多年的经验。

列出所有 Python 教程