如何在Python中使用'async for'?
我的意思是,对于,使用如何在Python中使用'async for'?,python,asynchronous,python-asyncio,Python,Asynchronous,Python Asyncio,我的意思是,对于,使用async可以得到什么。这是我用async为编写的代码,AIter(10)可以替换为get\u range() 但是代码的运行方式是sync而不是async 导入异步IO 异步def get_range(): 对于范围(10)内的i: 打印(f“开始{i}”) 等待asyncio.sleep(1) 打印(f“end{i}”) 产量一 AIter类: 定义初始化(self,N): self.i=0 self.N=N 定义(自我): 回归自我 异步定义(自): i=自我 打印(
async可以得到什么。这是我用async为
编写的代码,AIter(10)
可以替换为get\u range()
但是代码的运行方式是sync而不是async
导入异步IO
异步def get_range():
对于范围(10)内的i:
打印(f“开始{i}”)
等待asyncio.sleep(1)
打印(f“end{i}”)
产量一
AIter类:
定义初始化(self,N):
self.i=0
self.N=N
定义(自我):
回归自我
异步定义(自):
i=自我
打印(f“开始{i}”)
等待asyncio.sleep(1)
打印(f“end{i}”)
如果i>=self.N:
提出异步迭代
self.i+=1
返回i
异步def main():
AIter(10)中p的异步:
打印(f“finally{p}”)
如果名称=“\uuuuu main\uuuuuuuu”:
asyncio.run(main())
我排除的结果应该是:
start 1
start 2
start 3
...
end 1
end 2
...
finally 1
finally 2
...
然而,真正的结果是:
start 0
end 0
finally 0
start 1
end 1
finally 1
start 2
end 2
我知道我可以通过使用asyncio.gather
或asyncio.wait
获得异常结果
但是我很难理解这里使用async for
而不是简单的for
得到了什么
如果我想在多个功能
对象上循环并在一个对象完成后立即使用它们,那么使用async for
的正确方法是什么。例如:
async for f in feature_objects:
data = await f
with open("file", "w") as fi:
fi.write()
但是我很难理解这里使用async for
而不是简单的for
得到了什么
潜在的误解是期望自动并行化迭代。它不这样做,它只允许在异步源上进行顺序迭代。例如,您可以使用async For
对来自TCP流的行、来自websocket的消息或来自异步DB驱动程序的数据库记录进行迭代
对于
,上述任何一项都不适用于普通的,至少在不阻塞事件循环的情况下是如此。这是因为for
作为阻塞函数调用,并不等待其结果。您不能手动等待for
获得的元素,因为for
希望\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
通过引发停止迭代来发出迭代结束的信号。如果\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。这就是为什么async for
不仅在Python中引入,而且在with async/await和广义for
中引入的原因
如果要并行运行循环迭代,则需要将它们作为并行协程启动,并使用或等效工具在它们出现时检索它们的结果:
async def x(i):
print(f"start {i}")
await asyncio.sleep(1)
print(f"end {i}")
return i
# run x(0)..x(10) concurrently and process results as they arrive
for f in asyncio.as_completed([x(i) for i in range(10)]):
result = await f
# ... do something with the result ...
如果您不关心在结果到达时立即对结果做出反应,但您需要所有结果,那么您可以使用asyncio.gather
:
# run x(0)..x(10) concurrently and process results when all are done
results = await asyncio.gather(*[x(i) for i in range(10)])
@用户4815162342,是的,非常感谢。但我仍然在寻找异步源代码的一些示例。您可以为
语法添加一个使用async的示例吗?任何异步生成器都可以用作异步源。有关更具体的示例,请参见,例如,将一系列回调调用公开为异步迭代器,该迭代器可以使用async For
。顺便说一句,您可以尝试使用aiofiles以异步方式处理文件。感谢您提供了这一极其简单而精确的解释。请检查我的理解--您的两个代码片段(在asyncio.run(…)
,完成后…
和results=await…
必须在异步函数/方法中,在由asyncio.run(…)
启动的调用链中执行,对吗?@hBy2Py正确。问题(以及答案也是如此)为了简洁起见,省略这一部分。我喜欢解释者,但缺少了一个async for
loop@Roelant你说得对,一个例子会很有用。这个答案试图解决问题中提出的具体问题,这在当时是有意义的,但降低了它作为一般资源的价值。在这一点将使答案比现在长一点。希望有其他的SO问题可以澄清这个问题,如果没有,也许是时候提出一个新问题了。