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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33239308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 13:04:17  来源:igfitidea点击:

How to get exception message in Python properly

pythonexceptionexception-handling

提问by FrozenHeart

What is the best way to get exceptions' messages from components of standard library in Python?

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

I noticed that in some cases you can get it via messagefield like this:

我注意到在某些情况下你可以通过这样的message字段获得它:

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

but in some cases (for example, in case of socket errors) you have to do something like this:

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

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

I wondered is there any standard way to cover most of these situations?

我想知道是否有任何标准方法可以涵盖大多数这些情况?

采纳答案by ArtOfWarfare

If you look at the documentation for the built-in errors, you'll see that most Exceptionclasses assign their first argument as a messageattribute. Not all of them do though.

如果您查看内置错误文档,您会看到大多数Exception类将它们的第一个参数分配为message属性。但并非所有人都这样做。

Notably,EnvironmentError(with subclasses IOErrorand OSError) has a first argument of errno, second of strerror. There is no message... strerroris roughly analogous to what would normally be a message.

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

More generally, subclasses of Exceptioncan do whatever they want. They may or may not have a messageattribute. Future built-in Exceptions may not have a messageattribute. Any Exceptionsubclass imported from third-party libraries or user code may not have a messageattribute.

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

I think the proper way of handling this is to identify the specific Exceptionsubclasses you want to catch, and then catch only those instead of everything with an except Exception, then utilize whatever attributes that specific subclass defines however you want.

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

If you must printsomething, I think that printing the caught Exceptionitself is most likely to do what you want, whether it has a messageattribute or not.

如果您必须print做某事,我认为打印捕获Exception本身最有可能做您想做的事,无论它是否具有message属性。

You could also check for the message attribute if you wanted, like this, but I wouldn't really suggest it as it just seems messy:

如果你愿意,你也可以检查 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)

回答by Tosin Mash

To improve on the answer provided by @artofwarfare, here is what I consider a neater way to check for the messageattribute and print it or print the Exceptionobject as a fallback.

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

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

The call to repris optional, but I find it necessary in some use cases.

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



Update #1:

更新 #1:

Following the comment by @MadPhysicist, here's a proof of why the call to reprmight be necessary. Try running the following code in your interpreter:

@MadPhysicist发表评论之后,这里证明了为什么repr可能需要调用。尝试在解释器中运行以下代码:

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


Update #2:

更新#2:

Here is a demo with specifics for Python 2.7 and 3.5: https://gist.github.com/takwas/3b7a6edddef783f2abddffda1439f533

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

回答by Bill Z

I had the same problem. I think the best solution is to use log.exception, which will automatically print out stack trace and error message, such as:

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

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