【问题标题】:Which key failed in Python KeyError?Python KeyError 中哪个键失败?
【发布时间】:2022-02-05 03:55:41
【问题描述】:

如果我捕获到KeyError,我如何判断查找失败的原因?

def poijson2xml(location_node, POI_JSON):
  try:
    man_json = POI_JSON["FastestMan"]
    woman_json = POI_JSON["FastestWoman"]
  except KeyError:
    # How can I tell what key ("FastestMan" or "FastestWoman") caused the error?
    LogErrorMessage ("POIJSON2XML", "Can't find mandatory key in JSON")

【问题讨论】:

  • 由于无论如何您都必须在失败的键上进行分支,因此将每个查找放在单独的 try 语句中可能更清楚。

标签: python python-3.x


【解决方案1】:

获取当前异常(在这种情况下我使用了as e);那么对于KeyError,第一个参数是引发异常的键。因此我们可以这样做:

except KeyError as e:  # One would do it as 'KeyError, e:' in Python 2.
    cause = e.args[0]

这样,您就有了存储在cause 中的违规密钥。

扩展您的示例代码,您的日志可能如下所示:

def poijson2xml(location_node, POI_JSON):
  try:
    man_json = POI_JSON["FastestMan"]
    woman_json = POI_JSON["FastestWoman"]
  except KeyError as e:
    LogErrorMessage ("POIJSON2XML", "Can't find mandatory key '"
    e.args[0]
    "' in JSON")

需要注意的是,e.message 在 Python 2 中有效,但在 Python 3 中无效,因此不应使用。

【讨论】:

  • 谢谢。我不认为这在任何地方都有记录?我在 Python 文档中找不到它。
  • @QuestionC BaseException.args 已记录在案,但其用途不够详细。
  • 这是可取的使用,因为它没有记录并且参数可能会改变?
【解决方案2】:

不确定您是否正在使用任何模块来帮助您 - 如果 JSON 作为 dict 传入,则可以使用 dict.get() 实现有用的目的。

def POIJSON2DOM (location_node, POI_JSON):
    man_JSON = POI_JSON.get("FastestMan", 'No Data for fastest man')
    woman_JSON = POI_JSON.get("FastestWoman", 'No Data  for fastest woman')
    #work with the answers as you see fit

dict.get() 接受两个参数 - 第一个是您想要的 key,第二个是在该键不存在时返回的值。

【讨论】:

  • 对不起,这么晚了,但我想你是在回答基本问题,而不是 OP 直接询问KeyError
【解决方案3】:

如果您导入sys 模块,您可以使用sys.exc_info() 获取异常信息

像这样:

def POIJSON2DOM (location_node, POI_JSON):
  try:
    man_JSON = POI_JSON["FastestMan"]
    woman_JSON = POI_JSON["FastestWoman"]

  except KeyError:

    # you can inspect these variables for error information
    err_type, err_value, err_traceback = sys.exc_info()

    REDI.LogErrorMessage ("POIJSON2DOM", "Can't find mandatory key in JSON")

【讨论】:

  • @Alex Thornton 的回答要简单得多,并且更直接地回答问题。顺便说一句,由于这被否决了,我的方法从根本上是否有问题?我已经使用过这种方法,如果它引起问题,我不想使用它。帮帮我:)
  • 我认为没有理由投反对票。在 Python 2.6 之前捕获异常的语法不太清楚,因此显式调用 sys.exc_info() 是一种合理的方法。
  • 不是反对者,但是:它比except Foo as e 更复杂,而且它是多线程代码中的竞争条件。如果两个线程在它们中的任何一个调用sys.exc_info 之前引发 KeyError 怎么办?两个线程都会看到相同的输出,因此其中一个可能是错误的。 except Foo as e 语法是原子操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-20
  • 2018-04-07
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
相关资源
最近更新 更多