在处理上述异常期间,发生了另一个异常

rod*_*dee 5 python python-3.x

我在下面的try-except中捕获JSON解析错误:

with open(json_file) as j:
    try:
        json_config = json.load(j)
    except ValueError as e:
        raise Exception('Invalid json: {}'.format(e))
Run Code Online (Sandbox Code Playgroud)

为什么要During handling of the above exception, another exception occurred打印出来,我该如何解决?

json.decoder.JSONDecodeError: Expecting ',' delimiter: line 103 column 9 (char 1093)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
<....>
raise Exception('Invalid json: {}'.format(e))
Exception: Invalid json: Expecting ',' delimiter: line 103 column 9 (char 1093)
Run Code Online (Sandbox Code Playgroud)

Mar*_*lli 9

由于您从except语句内部引发了另一个异常,python 只是告诉您这一点。

换句话说,通常您except用来处理异常而不是使程序失败,但在这种情况下,您在已经处理了一个异常的同时引发了另一个异常,这就是 python 告诉您的。

如果这是您想要的行为,那真的没有什么可担心的。如果您想“摆脱”该消息,您也许可以在不引发另一个异常的情况下向输出写入一些内容,或者只是在不使用try/except语句的情况下使程序停止。


正如史蒂文所建议的,你可以这样做:

raise Exception('Invalid json: {}'.format(e)) from e
Run Code Online (Sandbox Code Playgroud)

打印两个异常,如下所示:

raise Exception('Invalid json: {}'.format(e)) from e
Run Code Online (Sandbox Code Playgroud)

或者你可以这样做:

raise Exception('Invalid json: {}'.format(e)) from None
Run Code Online (Sandbox Code Playgroud)

抑制第一个并且只记录Invalid json...异常。


顺便说一句,做类似的事情raise Exception('Invalid json: {}'.format(e))并没有多大意义,在这一点上你可以只留下原始异常,因为你没有向它添加太多信息。

  • 他还可以从 e` 中执行 `raise Exception('Invalid json: {}'.format(e)) 并打印出带有消息“上述异常是以下异常的直接原因:”的两个异常。或者他可以执行 `raise Exception('Invalid json: {}'.format(e)) from None` 这将抑制异常链并仅显示他提出的异常。 (2认同)

Ska*_*kam 7

当前,您ValueError在另一个捕获的异常内引发异常时遇到了问题。这种解决方案的理由对我来说没有多大意义,但是如果您改变

raise Exception('Invalid json: {}'.format(e))
Run Code Online (Sandbox Code Playgroud)

raise Exception('Invalid json: {}'.format(e)) from None
Run Code Online (Sandbox Code Playgroud)

编写最终代码。

with open(json_file) as j:
    try:
        json_config = json.load(j)
    except ValueError as e:
        raise Exception('Invalid json: {}'.format(e)) from None
Run Code Online (Sandbox Code Playgroud)

您应该获得捕获异常的预期结果。

例如

>>> foo = {}
>>> try:
...     var = foo['bar']
... except KeyError:
...     raise KeyError('No key bar in dict foo') from None
...
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
KeyError: 'No key bar in dict foo'
Run Code Online (Sandbox Code Playgroud)

抱歉,我无法为您解释为什么这特别有效,但似乎可以解决问题。

更新: 好像有一个PEP文档解释了如何在异常警告中抑制这些异常。

  • 非常感谢您链接到 PEP 文档。这是完全有道理的。语法是“raise &lt;Exception&gt; from &lt;Context Exception&gt;”。“上下文”基本上是您正在创建的异常的“父级”。默认情况下,父上下文是调用堆栈中的前一个异常(被“ except:”捕获的异常)。因此,通过显式地将上下文设置为“无”,我们说“不提供任何先前的上下文”。这意味着我们在“例外捕获器块”中抛出干净异常的最终语法是“从 None 引发&lt;新异常&gt;”。说得通。 (4认同)