在 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。但是KeyboardInterrupt
和SystemExit
不是Exception
的子类,所以你的最后一句话具有误导性。
@Aya:如果要捕获所有异常类型,包括KeyboardInterrupt
和SystemExit
,请捕获BaseException
而不是Exception
。这仍然无法处理裸字符串异常(或您以某种方式设法在解释器背后引发的不相关类型的异常 - 在 C 扩展模块中很容易意外发生,即使在纯中故意也不那么容易做到Python);为此,您确实需要一个裸露的except
。
这是标准库中的one example。当第三方库 foo-0.88 引发 ValueError
,但 0.89 引发 TypeError
或 foo.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的主要内容,如果未能解决你的问题,请参考以下文章