如何在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问题可以澄清这个问题,如果没有,也许是时候提出一个新问题了。