跳转至

19. 异步推导式

19. Asynchronous Comprehensions

当我们想到“Pythonic”时,推导式(例如列表推导式和字典推导式)是 Python 的特征之一。

这是我们执行循环的一种与许多其他语言不同的方式。

Asyncio 允许我们使用异步推导式。

我们可以通过“async for”表达式使用异步推导式来遍历异步生成器和异步迭代器。

让我们仔细看看。

Comprehensions, like list and dict comprehensions are one feature of Python when we think of “pythonic“.

It is a way we do loops that is different to many other languages.

Asyncio allows us to use asynchronous comprehensions.

We can traverse an asynchronous generators and asynchronous iterators using an asynchronous comprehension via the “async for” expression.

Let’s take a closer look.

19.1 什么是异步推导式

19.1 What are Asynchronous Comprehensions

异步推导式是经典推导式的异步版本。

Asyncio 支持两种类型的异步推导式,它们是“async for”推导和“await”推导。

PEP 530 添加了对在 列表、集合、字典推导和生成器表达式使用异步的支持

PEP 530: ASYNCHRONOUS COMPREHENSIONS, WHAT’S NEW IN PYTHON 3.6.

在我们讨论每一个之前,让我们首先回顾一下经典的推导式。

An async comprehension is an asynchronous version of a classical comprehension.

Asyncio supports two types of asynchronous comprehensions, they are the “async for” comprehension and the “await” comprehension.

PEP 530 adds support for using async for in list, set, dict comprehensions and generator expressions

PEP 530: ASYNCHRONOUS COMPREHENSIONS, WHAT’S NEW IN PYTHON 3.6.

Before we look at each, let’s first recall classical comprehensions.

19.2 推导式

19.2 Comprehensions

推导式允许以简洁的方式创建列表、字典和集合等数据集合。

列表推导式提供了一种创建列表的简洁方法。

LIST COMPREHENSIONS

列表推导式允许从新列表表达式中的 for 表达式创建列表。

例如:

...
# 使用列表理解创建列表
result = [a*2 for a in range(100)]

还支持创建字典和集合的推导式。

例如:

...
# 使用理解创建一个字典
result = {a:i for a,i in zip(['a','b','c'],range(3))}
# 使用推导式创建一个集合
result = {a for a in [1, 2, 3, 2, 3, 1, 5, 4]}

Comprehensions allow data collections like lists, dicts, and sets to be created in a concise way.

List comprehensions provide a concise way to create lists.

LIST COMPREHENSIONS

A list comprehension allows a list to be created from a for expression within the new list expression.

For example:

...
# create a list using a list comprehension
result = [a*2 for a in range(100)]

Comprehensions are also supported for creating dicts and sets.

For example:

...
# create a dict using a comprehension
result = {a:i for a,i in zip(['a','b','c'],range(3))}
# create a set using a comprehension
result = {a for a in [1, 2, 3, 2, 3, 1, 5, 4]}

19.3 异步推导式

19.3 Asynchronous Comprehensions

异步理解允许使用带有异步迭代的“async for”表达式来创建列表、集合或字典。

我们建议允许对内部列表、集合和字典推导中使用异步。

— PEP 530 – ASYNCHRONOUS COMPREHENSIONS

例如:

...
# 使用异步迭代器的异步列表理解
result = [a async for a in aiterable]

这将根据需要创建和调度协程或任务,并将其结果生成到列表中。

回想一下,“async for”表达式只能在协程和任务中使用。

另外,请记住,异步迭代器是产生可等待项的迭代器。

async for”表达式允许调用者遍历可等待项的异步迭代器并从每个迭代器中检索结果。

在内部,async for 循环将自动解析或等待每个可等待的、根据需要调度协程。

异步生成器自动实现异步迭代器的方法,也可以在异步推导式中使用。

例如:

...
# 使用异步生成器的异步列表推导式
result = [a async for a in agenerator]

An asynchronous comprehension allows a list, set, or dict to be created using the “async for” expression with an asynchronous iterable.

We propose to allow using async for inside list, set and dict comprehensions.

— PEP 530 – ASYNCHRONOUS COMPREHENSIONS

For example:

...
# async list comprehension with an async iterator
result = [a async for a in aiterable]

This will create and schedule coroutines or tasks as needed and yield their results into a list.

Recall that the “async for” expression may only be used within coroutines and tasks.

Also, recall that an asynchronous iterator is an iterator that yields awaitables.

The “async for” expression allows the caller to traverse an asynchronous iterator of awaitables and retrieve the result from each.

Internally, the async for loop will automatically resolve or await each awaitable, scheduling coroutines as needed.

An async generator automatically implements the methods for the async iterator and may also be used in an asynchronous comprehension.

For example:

...
# async list comprehension with an async generator
result = [a async for a in agenerator]

19.4 Await 推导式

19.4 Await Comprehensions

“await” 表达式也可以在列表、集合或字典推导中使用,称为await 推导

我们建议在异步和同步中都使用await推导列表推导

PEP 530 – ASYNCHRONOUS COMPREHENSIONS

与异步理解一样,它只能在异步协程或任务中使用。

这允许通过挂起和等待一系列可等待项来创建数据结构,例如列表。

例如:

...
# 在可等待对象合集中使用await列表推导
results = [await a for a in awaitables]

这将通过依次等待每个可等待项来创建结果列表。

当前协程将被挂起以顺序执行可等待项,这与使用 asyncio.gather() 并发执行它们不同,并且可能更慢。

您可以在教程中了解有关异步推导的更多信息:

接下来,我们将探索如何使用 asyncio 中的子进程来运行命令。

The “await” expression may also be used within a list, set, or dict comprehension, referred to as an await comprehension.

We propose to allow the use of await expressions in both asynchronous and synchronous comprehensions

PEP 530 – ASYNCHRONOUS COMPREHENSIONS

Like an async comprehension, it may only be used within an asyncio coroutine or task.

This allows a data structure, like a list, to be created by suspending and awaiting a series of awaitables.

For example:

...
# await list compression with a collection of awaitables
results = [await a for a in awaitables]

This will create a list of results by awaiting each awaitable in turn.

The current coroutine will be suspended to execute awaitables sequentially, which is different and perhaps slower than executing them concurrently using asyncio.gather().

You can learn more about async comprehensions in the tutorial:

Next, we will explore how to run commands using subprocesses from asyncio.


最后更新: 2024年9月4日
创建日期: 2024年9月4日