在Python中进行异步for循环

2024-04-29 13:06:21 发布

您现在位置:Python中文网/ 问答频道 /正文

以下代码输出如下:

1 sec delay, print "1", 
1 sec delay, print "2", 
1 sec delay, print "1", 
1 sec delay, print "2"

如何修改为这样运行:

1 sec delay, print "1", print "1",
1 sec delay, print "2", print "2"

我希望它运行,以便for循环的两个实例同时开始执行。当每个实例执行时,它们将同时遇到第一个()函数,然后同时遇到第二个()函数,从而按上述顺序打印。

代码:

import asyncio

async def first():
    await asyncio.sleep(1)
    return "1"

async def second():
    await asyncio.sleep(1)
    return "2"

async def main():     
    for i in range(2):
      result = await first()
      print(result)
      result2 = await second()
      print(result2)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Tags: 实例函数代码loopasyncioforasyncreturn
3条回答

要同时运行这两个函数,可以使用^{}。但是,结果将按您提供的顺序提供给您。例如,如果你

results = await asyncio.gather(first(), second())

然后你就可以拿回[the result of first(), the result of second()]。如果希望在每次返回时都执行某些操作,则应显式地使用Tasksadd callbacks

从期望的输出来看,目标似乎是保持单个迭代的原样(即按顺序运行firstsecond),但同时并行执行这两个循环迭代。

假设您只想修改main(),可以这样实现:

async def main():
    async def one_iteration():
        result = await first()
        print(result)
        result2 = await second()
        print(result2)
    coros = [one_iteration() for _ in range(2)]
    await asyncio.gather(*coros)

上面没有按顺序迭代,而是为每个迭代任务创建一个协程,并使用^{}并行执行所有迭代。

注意,仅仅创建一个协程并不能开始执行它,因此大量的coros不会阻塞事件循环。

使用aysncio库,您可以使用aysncio.gather()

loop.run_until_complete(asyncio.gather(
  first(),
  second()
))

如果您还并行发送HTTP请求,这将非常有用:

loop.run_until_complete(asyncio.gather(
  request1(),
  request2()
))

相关问题 更多 >