如何正确地在Python中获取异常消息

时间:2015-10-20 14:23:46

标签: python exception exception-handling

在Python中从标准库的组件获取异常消息的最佳方法是什么?

我注意到在某些情况下你可以通过message字段获取它,如下所示:

try:
  pass
except Exception as ex:
  print(ex.message)

但在某些情况下(例如,在套接字错误的情况下),您必须执行以下操作:

try:
  pass
except socket.error as ex:
  print(ex)

我想知道是否有任何标准方法可以涵盖大部分情况?

5 个答案:

答案 0 :(得分:42)

如果查看documentation for the built-in errors,您会看到大多数Exception类将其第一个参数指定为message属性。但并非所有人都这样做。

值得注意的是,EnvironmentError(子类IOErrorOSError)的第一个参数为errno,第二个参数为strerror。没有message ... strerror大致类似于通常的message

更一般地说,Exception的子类可以做任何他们想做的事情。它们可能具有message属性,也可能没有Exception属性。未来的内置message可能没有Exception属性。从第三方库或用户代码导入的任何message子类可能没有Exception属性。

我认为处理这个问题的正确方法是确定要捕获的特定except Exception子类,然后只使用print捕获那些而不是所有内容,然后使用特定子类的任何属性定义你想要的。

如果您必须Exception某些内容,我认为打印已捕获的message本身最有可能达到您想要的效果,无论它是否具有try: pass except Exception as e: # Just print(e) is cleaner and more likely what you want, # but if you insist on printing message specifically whenever possible... if hasattr(e, 'message'): print(e.message) else: print(e) 属性。

你也可以检查一下你想要的消息属性,就像这样,但我不会真的建议它,因为它看起来很乱:

public class PeopleInARoom
{

    public static void main(String[] args) {
        int humanNum = 10;
        String word = "people";

        while (humanNum < 0) {

            if (humanNum == 1) {
                word = "person"; //singular, as in one person.
            }

            System.out.println(humanNum + " " + word + "people in a room");
            System.out.println("Wait...somebody left!");
            humanNum = humanNum - 1;

            if (humanNum > 0) {
                System.out.println(humanNum + " " + word + "people in a room");
            } else {
                System.out.println("Hey, where has everybody gone?");
            }
        }
    }
}

答案 1 :(得分:15)

为了改进@artofwarfare提供的答案,我认为这是一种更简洁的方法来检查message属性并打印它或打印Exception对象作为后备。

try:
    pass 
except Exception as e:
    print getattr(e, 'message', repr(e))

repr的调用是可选的,但我发现在某些用例中这是必要的。

更新#1:

按照@MadPhysicist的评论,这里可以证明为什么可能需要拨打repr。尝试在解释器中运行以下代码:

try:
    raise Exception 
except Exception as e:
    print(getattr(e, 'message', repr(e)))
    print(getattr(e, 'message', str(e)))

更新#2:

这是一个包含Python 2.7和3.5细节的演示:https://gist.github.com/takwas/3b7a6edddef783f2abddffda1439f533

答案 2 :(得分:2)

from traceback import format_exc


try:
    fault = 10/0
except ZeroDivision:
    print(format_exc())

另一种可能是使用回溯模块中的 format_exc() 方法。

答案 3 :(得分:0)

我也有同样的问题。对此进行深入研究,我发现Exception类具有args属性,该属性捕获用于创建异常的参数。如果将except除外的异常范围缩小到一个子集,则应该能够确定它们的构造方式,从而确定哪个参数包含消息。

try:
   # do something that may raise an AuthException
except AuthException as ex:
   if ex.args[0] == "Authentication Timeout.":
      # handle timeout
   else:
      # generic handling

答案 4 :(得分:-1)

我有同样的问题。我认为最好的解决方案是使用log.exception,它将自动打印出堆栈跟踪和错误消息,例如:

try:
    pass
    log.info(Success')
except:
    log.exception('Failed')