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

Python 在处理上述异常期间,发生了另一个异常,python,python-3.x,Python,Python 3.x,我在下面尝试捕获JSON解析错误: with open(json_file) as j: try: json_config = json.load(j) except ValueError as e: raise Exception('Invalid json: {}'.format(e)) 为什么在处理上述异常的过程中,会打印出另一个异常,如何解决 json.decoder.JSONDecodeError: Expecting ',' deli

我在下面尝试捕获JSON解析错误:

with open(json_file) as j:
    try:
        json_config = json.load(j)
    except ValueError as e:
        raise Exception('Invalid json: {}'.format(e))
为什么在处理上述异常的过程中,
会打印出另一个异常
,如何解决

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)
json.decoder.JSONDecodeError:应为','分隔符:第103行第9列(字符1093)
在处理上述异常期间,发生了另一个异常:
回溯(最近一次呼叫最后一次):
引发异常('无效的json:{}'。格式(e))
异常:无效json:应为','分隔符:第103行第9列(字符1093)

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

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

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


根据建议,您可以:

raise Exception('Invalid json: {}'.format(e)) from e
要打印这两个异常,请执行以下操作:

回溯(最近一次呼叫最后一次):
文件“tmp.py”,第5行,在
从e引发异常('Invalid json:{}'。格式(e))
例外情况
上述异常是以下异常的直接原因:
回溯(最近一次呼叫最后一次):
json.decoder.JSONDecodeError:应为','分隔符:第103行第9列(字符1093)
或者您可以这样做:

raise Exception('Invalid json: {}'.format(e)) from None
要抑制第一个,只记录
无效json…
异常



顺便说一句,像
raiseexception('Invalid json:{}.format(e))
这样的操作没有多大意义,此时您可以不处理原始异常,因为您没有向其添加太多信息。

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

raise Exception('Invalid json: {}'.format(e))

制作你的终端代码

with open(json_file) as j:
    try:
        json_config = json.load(j)
    except ValueError as e:
        raise Exception('Invalid json: {}'.format(e)) from None
您应该能够获得捕获异常所需的结果

e、 g

>foo={}
>>>尝试:
...     var=foo['bar']
... 除KeyError外:
...     从“无”中升起键错误(“dict foo中没有键栏”)
...
回溯(最近一次呼叫最后一次):
文件“”,第4行,在
KeyError:“dict foo中没有键栏”
对不起,我不能给你一个解释,为什么这特别有效,但它似乎做的把戏

更新:
看起来有一个解释如何在异常警告中抑制这些异常。

Python警告您在处理另一个异常时抛出了一个异常。该警告用于在发生意外情况时提醒您,以便您了解原始异常。考虑下面这样的例子:

class Resource:
  def close(self):
     if cannot_close:
       raise Error("Cannot close")

  def write_data(self, data):
     ...

some_function():
  try:
    res = Resource()
    res.write_data("some data")
  except Error as e:
    res.close()
假设
write\u data
引发异常,但是
close
也意外地引发异常。当这种情况发生时,很高兴了解这两种例外情况。在大多数情况下,您希望了解由
write_data
引发的原始异常,但了解
close
中的异常有助于您了解
close
中发生的异常

with open(json_file) as j:
    try:
        json_config = json.load(j)
    except ValueError as e:
        raise Exception('Invalid json from file {}: {}'.format(json_file, e)) from e
但对于您的情况,您只是以一种新的方式重新启动原始错误。这样做可以提供更多上下文,例如:

with open(json_file) as j:
    try:
        json_config = json.load(j)
    except ValueError as e:
        raise Exception('Invalid json from file {}: {}'.format(json_file, e))
这将为您提供未能解析为JSON的文件的路径,这是原始异常消息中没有的有用上下文信息

因此,为了告诉Python您实际上是在重新引发原始异常,但是需要更多的上下文,您可以从e添加

with open(json_file) as j:
    try:
        json_config = json.load(j)
    except ValueError as e:
        raise Exception('Invalid json from file {}: {}'.format(json_file, e)) from e

这相当于Java中的“异常链接”,您可以将原始异常提供给新异常的构造函数。

他可能的重复项也可以从e中执行
引发异常('Invalid json:{}'。format(e))
并将这两个异常与消息一起打印出来“上述异常是以下异常的直接原因:”。或者他可以从“无”中执行
引发异常('Invalid json:{}.format(e)),这将抑制异常链接并仅显示他引发的异常。非常感谢链接到PEP文档。这非常有意义。
引发自
是语法。”“上下文”基本上是您正在创建的异常的“父级”。默认情况下,父级上下文是调用堆栈中的前一个异常(被
捕获的异常除外:
)。因此,通过显式地将上下文设置为
,我们说“不提供任何前一个上下文”“。这意味着在“除catcher块”中抛出干净异常的最终语法是
从None提升
。有道理。
with open(json_file) as j:
    try:
        json_config = json.load(j)
    except ValueError as e:
        raise Exception('Invalid json from file {}: {}'.format(json_file, e)) from e