documentation for asyncio.gather人说

如果return_exceptions为False(默认),则引发的第一个异常为

然而,从一个简单的测试来看,如果其中一个任务在return_exceptions为False时引发异常,那么所有其他等待的任务都将被取消(或者更准确地说,如果我不清楚术语,其他等待的任务将无法完成其工作):

import asyncio

async def factorial(name, number, raise_exception=False):
    # If raise_exception is True, will raise an exception when
    # the loop counter > 3
    f = 1
    for i in range(2, number + 1):
        print(f'  Task {name}: Compute factorial({i})...')

        if raise_exception and i > 3:
            print(f'  Task {name}: raising Exception')
            raise Exception(f'Bad Task {name}')

        await asyncio.sleep(1)
        f *= i
    print(f'==>> Task {name} DONE: factorial({number}) = {f}')
    return f

async def main():
    tasks = [factorial('A', 5),  # this will not be finished
             factorial('B', 10, raise_exception=True),
             factorial('C', 2)]

    try:
        results = await asyncio.gather(*tasks)
        print('Results:', results)
    except Exception as e:
        print('Got an exception:', e)

asyncio.run(main())

这段代码所做的只是为了简化,它定义了3个任务,并调用了asyncio.gather()个.其中一个任务在另一个任务完成之前引发异常,而另一个任务未完成.

事实上,我甚至无法理解文档中所说的内容——如果一个异常被等待gather的任务引发并捕获,我甚至无法获得返回的结果(即使另一个任务以某种方式完成).

我遗漏了什么,或者文档有问题吗?

这是用Python 3.7.2测试的.

推荐答案

我已经运行了您的代码,并获得了以下输出,正如文档中预期的那样.

  Task C: Compute factorial(2)...
  Task A: Compute factorial(2)...
  Task B: Compute factorial(2)...
==>> Task C DONE: factorial(2) = 2
  Task A: Compute factorial(3)...
  Task B: Compute factorial(3)...
  Task A: Compute factorial(4)...
  Task B: Compute factorial(4)...
  Task B: raising Exception
Got an exception: Bad Task B
  Task A: Compute factorial(5)...
==>> Task A DONE: factorial(5) = 120

What's going on

  1. 任务A、B和C提交到队列;
  2. C最早完成时,所有任务都在运行.
  3. 任务B引发异常.
  4. await asyncio.gater()立即返回屏幕,print('Got an exception:', e)立即返回屏幕.
  5. Task A continues to run and print "==>> Task A DONE ..."

What's wrong with your test

正如@deceze comments 的那样,

要修复它,请在main()函数的末尾添加await asyncio.sleep(20).

Python-3.x相关问答推荐

丢弃重复的索引,并在多索引数据帧中保留一个

被多个\n拆分并保留

在Pandas 数据帧中为小于5位的邮政编码添加前导零

从PYTHON中获取单行和多行的Rguar表达式

在特定条件下从 DataFrame 中提取特定组

如何将多输入数据加载器传递给单输入模型

无法提出给定 for 循环的原因 (Python 3.11)

如何将搜索结果中的所有值保存在另一个列表中?

如何在pyspark的列中按连续1分组并保持具有特定大小的组

Python pandas将单元格值移动到同一行中的另一个单元格

集合操作:应该只适用于集合,但适用于 dict_keys?

python3:字节与字节数组,并转换为字符串和从字符串转换

有没有更好的方法来判断一个数字是否是两个数字的范围

预分配一个无列表

Python在OrderedDict中 Select 第i个元素

为什么 string.maketrans 在 Python 3.1 中不起作用?

如何替换 Python pathlib.Path 中的子字符串?

将 Python SIGINT 重置为默认信号处理程序

如何从Pandas 中的字符串中提取前8个字符

如何更改 tkinter 文本小部件中某些单词的 colored颜色 ?