Python语言峰会:PEP 654 - 异常组和除外

2021-05-16 18:27:59

PEP 654由Irit Katriel,Yury Selivanov和Guido Van Rossum作着。此PEP目前正在草稿阶段。作者分享了它,为什么我们需要它,以及他们拒绝的想法。

此PEP的目的是帮助Python用户处理无关的异常。现在,如果你'重新处理几个不相关的异常,你可以:

返回一个例外,而不是提高它们,在这种情况下,它们成为错误代码而不是例外,因此您可以使用异常处理机制处理它们

在包装器异常中包装例外列表,并将其用作错误代码列表,其仍然可以用例外处理机制处理。

除了*子句之外,他们最多可以执行一次。每个叶例异常都将由其中一个除外,最多。

在迄今为止发生的PEP的讨论中,对这些想法没有重大反对,但仍有关于如何代表一个例外组的分歧。异常组可以嵌套,每个异常都有自己的元数据:

最初,作者认为他们可以使例外群体迭代,但那不是最好的选择,因为必须保留元数据。他们的解决方案是使用.split()操作在叶子上拍摄条件并复制元数据:

运行错误与控制流错误之间存在一些差异,您需要考虑到'重新处理例外时:

在示例1中,存在具有直接误差的明确定义的操作。但在示例2中,有一个并发任务可以包含任何数量的代码,所以你不知道是什么导致的keyerror。在这种情况下,处理一个KeyError可能是有用的对日志记录,但它是' t否则有用。但还有其他例外情况可以更加有意义地处理:

重要的是要了解操作错误和控制流错误之间的差异,因为它们与尝试除外的差异:操作错误通常在他们发生的情况下处理并使用除外语句进行良好。

控制流误差基本上是信号,并且当前的试论语句的语义并不适用于它们。

在异步之前,它不是那么大的问题,即在那里的问题和#39; t进出了这些类型的控制流错误的机制,但现在它更重要的是我们有更好的处理方式有了这些问题。 Asyncio.gather()是一个不寻常的API,因为它具有由一个关键字参数控制的两个完全不同的操作模式,return_exceptions:

此API的问题是,如果发生错误,则仍然等待所有任务要完成。此外,您可以' t使用试验除了处理例外,而是必须解压缩这些任务的结果并手动检查它们,这可能是麻烦的。如果一个任务失败,那么将取消所有其他任务。 Asyncio的用户一直要求这种解决方案,但它需要一种处理例外的新方法,并且是PEP 654背后的灵感的一部分。

异常组是否应该是迭代仍然是一个开放的问题。为此工作,需要将追溯进行连接,共享部分复制,这是非常有效的。但是迭代是' T通常是使用异常组的正确方法。潜在的妥协可以是在Traceback.py中具有迭代实用程序。

除了处理异常组而不是添加*之外,作者认为教学除外,但是Bakwards兼容性问题会有太多。 他们还考虑了一次使用除外*条款。 向后兼容性问题' t在那里申请,但这将基本上是迭代,这将不会帮助。