为什么要“从原因中引起例外”,而不是“从原因中引起例外”?

时间:2019-10-12 15:27:23

标签: python python-3.x exception

让我详细说明这个隐秘的问题标题。

在Python 3中,我们提供了巧妙的异常链接功能,该功能可让您在异常传播过程中为异常添加更多上下文。

最近,我想在异常上附加额外的异常信息,但又不要直接抛出。该代码在生成器中进行了一些防御性处理,因此我想让其产生,因此我尝试了类似的操作:

def gen():
   for row in csv_file:
       try:
          yield parse(row)
       except Exception as e:
          yield RuntimeError(f"Bad row: {row}") from e

令我失望的是,这没有用!原来raise EXCEPTION from CAUSE是复合运算符,如PEP-3134所述。

要在我的代码中解决此问题,我手动设置了__cause__ = e并继续进行。但是,它仍然困扰着我为什么以这种方式实施。

想象,取而代之的是,我们有一个运算符from,其语法如下:EXCEPTION from CAUSE,除了抛出并返回新的{ {1}}。这样:

  • 它是兼容的,您仍然可以使用raise .. from ..语法(现在在内部将其解析为Exception
  • 这将使所有内容变得更“可组合” ,从而允许附加原因而不必抛出(特别是我的用例)。我可以,但这是异常的异常使用。
  • 大概,这也将使实现更加简单,因为您不需要修改和冲突退出原语(简单的raise .. from ..运算符)。从Python语言开发人员的角度来看,我将其视为运算符“替代形式”的主要论点。

我已经通过PEP / google进行过搜索,但是并没有真正找到任何理由。我尝试检查是否设置了raise (.. from ..)以外的其他内容,但事实并非如此。我附加了一些我用来检查的代码:

raise

它产生相同的回溯:

__cause__
def failing():
    raise RuntimeError("function failed!")


def cause_from():
    try:
        failing()
    except Exception as e:
        raise RuntimeError("extra info") from e

def cause_manual():
    try:
        failing()
    except Exception as e:
        ee = RuntimeError("extra info")
        ee.__cause__ = e
        raise ee

回溯中的唯一区别是引发异常的行($ python3 -c 'import exc; exc.cause_from()' Traceback (most recent call last): File "/tmp/exc.py", line 7, in cause_from failing() File "/tmp/exc.py", line 2, in failing raise RuntimeError("function failed!") RuntimeError: function failed! The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<string>", line 1, in <module> File "/tmp/exc.py", line 9, in cause_from raise RuntimeError("extra info") from e RuntimeError: extra info $ python3 -c 'import exc; exc.cause_manual()' Traceback (most recent call last): File "/tmp/exc.py", line 13, in cause_manual failing() File "/tmp/exc.py", line 2, in failing raise RuntimeError("function failed!") RuntimeError: function failed! The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<string>", line 1, in <module> File "/tmp/exc.py", line 17, in cause_manual raise ee RuntimeError: extra info )。 raise RuntimeError("extra info") from e版本看起来更具可读性。

所以这是我看到选择语法结构的唯一原因,我想知道这是否也是预期的动机?我有可能会错过raise ee作为复合运算符的微妙效果吗?

0 个答案:

没有答案