问题:如何在Python中正确获取异常消息
从Python标准库的组件中获取异常消息的最佳方法是什么?
我注意到在某些情况下,您可以通过如下message
字段获取它:
try:
pass
except Exception as ex:
print(ex.message)
但在某些情况下(例如在套接字错误的情况下),您必须执行以下操作:
try:
pass
except socket.error as ex:
print(ex)
我想知道是否有标准方法可以涵盖大多数情况?
回答 0
如果您查看有关内置错误的文档,则会看到大多数Exception
类将其第一个参数分配为message
属性。并非所有人都这样做。
值得注意的是,EnvironmentError
(与子类IOError
和OSError
)具有的第一自变量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)
回答 1
为了改善@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
我有同样的问题。我认为最好的解决方案是使用log.exception,它将自动打印出堆栈跟踪和错误消息,例如:
try:
pass
log.info('Success')
except:
log.exception('Failed')
回答 3
我也有同样的问题。对此进行深入研究,我发现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