as_completed 识别协程对象

as_completed identifying coroutie objects

我正在使用 asyncio 按以下方式等待协程集:

# let's assume we have fn defined and that it can throw an exception

coros_objects = []
for x in range(10):
    coros_objects.append(fn(x))


for c in asyncio.as_completed(coros_objects):
    try:
       y = await c
    exception:
       # something
       # if possible print(x)

问题是我怎么知道哪个协程失败了以及哪个参数失败了? 我可以将 "x" 附加到输出,但这只会给我有关成功执行的信息。

我知道表格顺序是因为它与 coros_objects

的顺序不同

我能以某种方式确定 coro 刚刚产生的结果吗?

Question is how can I know which coroutine failed and for which argument?

你不能用现在的 as_completed。一旦 this PR 被合并,就可以通过将信息附加到未来(因为 as_completed 将产生原始期货)。目前有两种解决方法:

  • 将协程执行包装在一个包装器中,该包装器捕获异常并存储它们,并且还存储您需要的原始参数,或者
  • 根本不使用 as_completed,而是使用 asyncio.wait.
  • 等工具编写自己的循环

第二个选项比大多数人预期的要容易,所以这里是(未经测试):

# create a list of tasks and attach the needed information to each
tasks = []
for x in range(10):
    t = asyncio.create_task(fn(x))
    t.my_task_arg = x
    tasks.append(t)

# emulate as_completed with asyncio.wait()
while tasks:
    done, tasks = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
    for t in done:
        try:
            y = await t
        except Exception as e:
            print(f'{e} happened while processing {t.my_task_arg}')