Python 异步理解 - 它们是如何工作的?
Python Asynchronous Comprehensions - how do they work?
我无法理解 Python 3.6 中引入的异步理解的使用。作为免责声明,我在 Python.
中一般没有太多处理异步代码的经验
what's new for Python 3.6文档中给出的例子是:
result = [i async for i in aiter() if i % 2]
在PEP中,展开为:
result = []
async for i in aiter():
if i % 2:
result.append(i)
I think I understand that the aiter()
function gets asynchronously calculated, so that the each iteration of aiter
can proceed without the previous one necessary returned yet aiter()
函数的每次迭代都可以继续进行,而不必返回前一个(或者这个理解有误?)
我不确定这将如何转化为此处的列表理解。结果是否按照返回的顺序放入列表中?或者在最终列表中是否有有效的 'placeholders' 以便每个结果以正确的顺序放在列表中?还是我想的不对?
此外,是否有人能够提供一个真实示例来说明适用的用例和 async
的基本机制?
I think I understand that the aiter()
function gets called asynchronously, so that each iteration of aiter
can proceed without the previous one necessarily returning yet (or is this understanding wrong?).
这种理解是错误的。 async for
循环的迭代不能并行执行。 async for
与常规 for
循环一样顺序。
async for
的异步部分是它让迭代器 await
代表协程迭代它。它仅适用于异步协同程序,并且仅适用于特殊的异步可迭代对象。除此之外,它基本上就像一个常规的 for
循环。
您基本上是在询问 async for
循环如何在常规循环上工作。您现在可以在列表理解中使用这样的循环在这里没有任何区别;这只是一种避免重复 list.append()
调用的优化,就像正常的列表理解一样。
然后 async for
循环,只需等待迭代协议的每个下一步,常规 for
循环将阻塞。
为了说明,想象一个正常的 for
循环:
for foo in bar:
...
对于这个循环,Python 本质上是这样做的:
bar_iter = iter(bar)
while True:
try:
foo = next(bar_iter)
except StopIteration:
break
...
next(bar_iter)
调用不是异步的;它会阻塞。
现在将 for
替换为 async 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
...
上面例子中的aiter()
和anext()
是虚构的函数;它们在功能上完全等同于它们的 iter()
和 next()
兄弟,但它们使用 __aiter__
和 __anext__
而不是 __iter__
和 __next__
。也就是说,存在用于相同功能的异步挂钩,但通过前缀 a
.
与它们的非异步变体区分开来
await
关键字存在关键差异,因此对于每次迭代,async for
循环都会产生控制权,因此其他协程可以 运行 代替。
再次重申,所有这些都已添加到 Python 3.5(请参阅 PEP 492),Python 3.6 中的所有新内容是您可以使用这样的列表理解中的循环也是如此。就此而言,在生成器表达式以及集合和字典理解中。
最后但并非最不重要的一点是,同一组更改也使得在理解的表达式部分中使用 await <expression>
成为可能,因此:
[await func(i) for i in someiterable]
现在可以了。
我无法理解 Python 3.6 中引入的异步理解的使用。作为免责声明,我在 Python.
中一般没有太多处理异步代码的经验what's new for Python 3.6文档中给出的例子是:
result = [i async for i in aiter() if i % 2]
在PEP中,展开为:
result = []
async for i in aiter():
if i % 2:
result.append(i)
I think I understand that the aiter()
function gets asynchronously calculated, so that the each iteration of aiter
can proceed without the previous one necessary returned yet aiter()
函数的每次迭代都可以继续进行,而不必返回前一个(或者这个理解有误?)
我不确定这将如何转化为此处的列表理解。结果是否按照返回的顺序放入列表中?或者在最终列表中是否有有效的 'placeholders' 以便每个结果以正确的顺序放在列表中?还是我想的不对?
此外,是否有人能够提供一个真实示例来说明适用的用例和 async
的基本机制?
I think I understand that the
aiter()
function gets called asynchronously, so that each iteration ofaiter
can proceed without the previous one necessarily returning yet (or is this understanding wrong?).
这种理解是错误的。 async for
循环的迭代不能并行执行。 async for
与常规 for
循环一样顺序。
async for
的异步部分是它让迭代器 await
代表协程迭代它。它仅适用于异步协同程序,并且仅适用于特殊的异步可迭代对象。除此之外,它基本上就像一个常规的 for
循环。
您基本上是在询问 async for
循环如何在常规循环上工作。您现在可以在列表理解中使用这样的循环在这里没有任何区别;这只是一种避免重复 list.append()
调用的优化,就像正常的列表理解一样。
然后 async for
循环,只需等待迭代协议的每个下一步,常规 for
循环将阻塞。
为了说明,想象一个正常的 for
循环:
for foo in bar:
...
对于这个循环,Python 本质上是这样做的:
bar_iter = iter(bar)
while True:
try:
foo = next(bar_iter)
except StopIteration:
break
...
next(bar_iter)
调用不是异步的;它会阻塞。
现在将 for
替换为 async 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
...
上面例子中的aiter()
和anext()
是虚构的函数;它们在功能上完全等同于它们的 iter()
和 next()
兄弟,但它们使用 __aiter__
和 __anext__
而不是 __iter__
和 __next__
。也就是说,存在用于相同功能的异步挂钩,但通过前缀 a
.
await
关键字存在关键差异,因此对于每次迭代,async for
循环都会产生控制权,因此其他协程可以 运行 代替。
再次重申,所有这些都已添加到 Python 3.5(请参阅 PEP 492),Python 3.6 中的所有新内容是您可以使用这样的列表理解中的循环也是如此。就此而言,在生成器表达式以及集合和字典理解中。
最后但并非最不重要的一点是,同一组更改也使得在理解的表达式部分中使用 await <expression>
成为可能,因此:
[await func(i) for i in someiterable]
现在可以了。