Python异步理解 - 它们如何工作?

And*_*Guy 30 python asynchronous list-comprehension python-3.6

我无法理解Python 3.6中引入的异步理解的使用.作为免责声明,我在Python中处理异步代码方面没有太多经验.

Python 3.6文档中新增的示例是:

result = [i async for i in aiter() if i % 2]
Run Code Online (Sandbox Code Playgroud)

PEP中,这扩展到:

result = []
async for i in aiter():
    if i % 2:
        result.append(i)
Run Code Online (Sandbox Code Playgroud)

我理解该aiter()函数是异步调用的,所以每次迭代都aiter可以继续进行,而前一个迭代还没有必要返回(或者这种理解是错误的吗?).

我不确定的是,这将如何转化为列表理解.结果是按照返回的顺序放入列表中的吗?或者在最终列表中是否有有效的"占位符",以便每个结果都以正确的顺序放在列表中?或者我是否以错误的方式思考这个问题?

另外,是否有人能够提供一个真实的例子来说明适用的用例和这样的async理解中的基本机制?

Mar*_*ers 20

您基本上是在询问async for循环如何在常规循环中运行.你现在可以在列表理解中使用这样的循环在这里没有任何区别; 这只是一种避免重复list.append()调用的优化,就像正常的列表理解一样.

一个async for循环然后,只需等待迭代协议,其中一个普通的每个下一步骤for循环会阻塞.

为了说明,想象一个正常的for循环:

for foo in bar:
    ...
Run Code Online (Sandbox Code Playgroud)

对于这个循环,Python实际上是这样做的:

bar_iter = iter(bar)
while True:
    try:
        foo = next(bar_iter)
    except StopIteration:
        break
    ...
Run Code Online (Sandbox Code Playgroud)

next(bar_iter)调用不是异步的; 它阻止.

现在替换forasync for,以及Python做了哪些更改:

bar_iter = aiter(bar)  # aiter doesn't exist, but see below
while True:
    try:
        foo = await anext(bar_iter)  # anext doesn't exist, but see below
    except StopIteration:
        break
    ...
Run Code Online (Sandbox Code Playgroud)

在上面的例子aiter()anext()是虚构的功能; 这些是他们iter()next()弟兄们在功能上完全相同,但不是__iter____next__这些使用__aiter____anext__.也就是说,异步挂钩存在相同的功能,但通过前缀区别于它们的非异步变体a.

await存在的关键区别,所以对于每个迭代一个关键字async for循环的产率进行控制,从而其他协程可以代替运行.

同样,为了重新迭代,所有这些都已经在Python 3.5中添加(参见PEP 492),Python 3.6中的所有新功能都是你可以在列表推导中使用这样的循环.在生成器表达式和set和dict理解中,就此而言.

最后但同样重要的是,同一组更改还可以await <expression>在理解的表达式部分中使用,因此:

[await func(i) for i in someiterable]
Run Code Online (Sandbox Code Playgroud)

现在可以了.


use*_*ica 11

我理解该aiter()函数是异步调用的,所以每次迭代都aiter可以继续进行,而前一个迭代还没有必要返回(或者这种理解是错误的吗?).

这种理解是错误的.async for循环的迭代不能并行执行.async for与常规for循环一样顺序.

异步部分async for是它让迭代器await代表协程迭代它.它仅用于异步协同程序,仅用于特殊的异步迭代.除此之外,它主要就像一个常规for循环.