【问题标题】:Catch KeyError in Python在 Python 中捕获 KeyError
【发布时间】: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:

标签: python try-catch except


【解决方案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
            

            【讨论】:

              猜你喜欢
              • 2021-11-22
              • 2018-12-19
              • 1970-01-01
              • 2013-05-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-08-23
              相关资源
              最近更新 更多