在 Python 中捕获 KeyError

Posted

技术标签:

【中文标题】在 Python 中捕获 KeyError【英文标题】:Catch KeyError in Python 【发布时间】:2013-04-15 18:19:31 【问题描述】:

如果我运行代码:

connection = manager.connect("I2Cx")

程序崩溃并报告 KeyError 因为 I2Cx 不存在(应该是 I2C)。

但如果我这样做:

try:
    connection = manager.connect("I2Cx")
except Exception, e:
    print e

它不会为 e 打印任何内容。我希望能够打印抛出的异常。如果我尝试用除以零操作来做同样的事情,它在两种情况下都会被正确捕获和报告。我在这里错过了什么?

【问题讨论】:

旁注:除非您需要 pre-2.5 兼容性,否则您应该写 except Exception as e: 而不是 except Exception, e: 【参考方案1】:

如果它引发一个没有消息的 KeyError,那么它不会打印任何东西。如果你这样做......

try:
    connection = manager.connect("I2Cx")
except Exception as e:
    print repr(e)

...你至少会得到异常类名。

更好的选择是使用多个except 块,并且只“捕获”您打算处理的异常...

try:
    connection = manager.connect("I2Cx")
except KeyError as e:
    print 'I got a KeyError - reason "%s"' % str(e)
except IndexError as e:
    print 'I got an IndexError - reason "%s"' % str(e)

捕捉所有异常是有正当理由的,但如果你这样做了,你几乎应该总是重新引发它们......

try:
    connection = manager.connect("I2Cx")
except KeyError as e:
    print 'I got a KeyError - reason "%s"' % str(e)
except:
    print 'I got another exception, but I should re-raise'
    raise

...因为如果用户按下 CTRL-C,您可能不想处理 KeyboardInterrupt,如果 try-block 调用 sys.exit(),您可能也不想处理 SystemExit

【讨论】:

我认为他的问题更多是catch 部分而不是实际打印...但是是的,这也解决了这个问题 @JoranBeasley @JoranBeasley catch 更可能是错字,因为如果在真实代码中,OP 会出现不同的错误。 +1。但是KeyboardInterruptSystemExit 不是Exception 的子类,所以你的最后一句话具有误导性。 @Aya:如果要捕获所有异常类型,包括KeyboardInterruptSystemExit,请捕获BaseException 而不是Exception。这仍然无法处理裸字符串异常(或您以某种方式设法在解释器背后引发的不相关类型的异常 - 在 C 扩展模块中很容易意外发生,即使在纯中故意也不那么容易做到Python);为此,您确实需要一个裸露的except 这是标准库中的one example。当第三方库 foo-0.88 引发 ValueError,但 0.89 引发 TypeErrorfoo.FooError 时,我最常使用它。 (替代方案是两个复制粘贴的except 块,或者一个except Exception as e:if isinstance(e, (ValueError, TypeError)): raise,或者无缘无故需要 foo-0.89 或更高版本……)【参考方案2】:

我正在使用 Python 3.6,并且在 Exception 和 e 之间使用逗号不起作用。我需要使用以下语法(仅供任何想知道的人使用)

try:
    connection = manager.connect("I2Cx")
except KeyError as e:
    print(e.message)

【讨论】:

【参考方案3】:

尝试 print(e.message) 这应该能够打印您的异常。

try:
    connection = manager.connect("I2Cx")
except Exception, e:
    print(e.message)

【讨论】:

【参考方案4】:

如果您不想处理错误,只需 NoneType 并使用 get() 例如:

manager.connect.get("")

【讨论】:

【参考方案5】:

您也可以尝试使用get(),例如:

connection = manager.connect.get("I2Cx")

如果密钥不存在,则不会引发KeyError

如果键不存在,您也可以使用第二个参数指定默认值。

【讨论】:

【参考方案6】:

您应该查阅引发异常的任何库的文档,以了解如何从其异常中获取错误消息。

或者,调试这种事情的一个好方法是说:

except Exception, e:
    print dir(e)

查看 e 具有哪些属性 - 您可能会发现它具有 message 属性或类似属性。

【讨论】:

【参考方案7】:

我不认为 python 有一个陷阱:)

try:
    connection = manager.connect("I2Cx")
except Exception, e:
    print e

【讨论】:

以上是关于在 Python 中捕获 KeyError的主要内容,如果未能解决你的问题,请参考以下文章

在python中捕获人脸框

在 Python 中捕获 Control-C

Python:在 QListWidget 中捕获重新排序事件?

如何在 python 中捕获异常(在 C++ 中引起)

如何在unittest中捕获python子进程stdout

从 Python 中捕获音频