在Python中捕获KeyError异常。

59

如果我运行这段代码:

connection = manager.connect("I2Cx")
程序崩溃并报告 KeyError,因为 I2Cx 不存在(应该是 I2C)。
但如果我这样做:
try:
    connection = manager.connect("I2Cx")
except Exception, e:
    print e

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


4
附注:除非需要向前兼容2.5版本,否则应该使用except Exception as e:代替except Exception, e: - abarnert
7个回答

98

如果引发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

因为您可能不希望处理KeyboardInterrupt(如果用户按下CTRL-C)或SystemExit(如果try块调用sys.exit())。


我认为他的问题更多是catch部分而不是实际打印...但是是的,这也解决了那个问题。 - Joran Beasley
1
@JoranBeasley,catch 更可能是一个打字错误,因为如果在真正的代码中出现这种情况,OP 将会得到不同的错误。 - Aya
1
+1。但是KeyboardInterruptSystemExit不是Exception的子类,所以你最后一句话有误导性。 - abarnert
1
@Aya:如果您想捕获所有异常类型,包括 KeyboardInterruptSystemExit,请捕获 BaseException 而不是 Exception。这仍然不能处理裸字符串异常(或者一些您在解释器背后某种方式意外触发的不相关类型的异常——在C扩展模块中很容易发生错误,在纯Python中即使有意也不容易实现);为此,您确实需要使用裸 except - abarnert
1
这是标准库中的一个例子。当第三方库foo-0.88引发ValueError,但0.89引发TypeErrorfoo.FooError时,我倾向于最常使用它。(另外两个选择是复制粘贴两个except块,或者使用except Exception as e:if isinstance(e, (ValueError, TypeError)): raise,或者无缘无故地要求foo-0.89或更高版本...) - abarnert
显示剩余6条评论

20

我正在使用Python 3.6,用逗号将Exception和e分隔开无效。 我需要使用以下语法(仅供参考)

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

6

您应该查看抛出异常的库的文档,以了解如何从其异常中获取错误消息。

或者,调试此类问题的一个好方法是执行以下操作:

except Exception, e:
    print dir(e)

要查看e有哪些属性 - 你很可能会发现它有一个message属性或类似的属性。


2

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

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

如果键不存在,使用这种方法不会引发KeyError异常。

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


1
如果您不想处理错误,只需使用“NoneType”并使用“get()”即可。 例如:
manager.connect.get("")

0

我认为Python没有catch :)

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

-2
尝试使用print(e.message)打印您的异常,这应该能够打印出来。
try:
    connection = manager.connect("I2Cx")
except Exception, e:
    print(e.message)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接