从Python标准库的组件中获取异常消息的最佳方法是什么?
我注意到在某些情况下,您可以通过如下message
字段获取它:
try:
pass
except Exception as ex:
print(ex.message)
但在某些情况下(例如在套接字错误的情况下),您必须执行以下操作:
try:
pass
except socket.error as ex:
print(ex)
我想知道是否有标准方法可以涵盖大多数情况?
从Python标准库的组件中获取异常消息的最佳方法是什么?
我注意到在某些情况下,您可以通过如下message
字段获取它:
try:
pass
except Exception as ex:
print(ex.message)
但在某些情况下(例如在套接字错误的情况下),您必须执行以下操作:
try:
pass
except socket.error as ex:
print(ex)
我想知道是否有标准方法可以涵盖大多数情况?
.message
错误是否是标准方式?
print(msg)
只是print(str(msg))
message
已被弃用。
Answers:
如果您查看有关内置错误的文档,则会看到大多数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)
str(ex)
而不仅仅是ex
?
print()
自动呼叫str()
您。没有必要手动手动调用它,尽管它无害,因为调用str()
字符串只会返回字符串本身。
str()
message类型的问题unicode
。
为了改善@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
getattr
如果传入的对象没有请求的属性,则引发异常。如果您想做类似的事情,我认为您应该使用可选的第三个参数getattr
,例如:print getattr(e, 'message', e)
。比我做的好得多。另一个选择是print(e.message if hasattr(e, 'message') else e)
。
str
而不是repr
。
str
,repr
只添加了类名。repr
我建议不要使用,而是使用print('{e.__class__.__name__}: {e}'.format(e=e))
。打印输出更清洁,并粘附在提升输出本身上。
'{e.__class__.__module__}.{e.__class__.__name__}: {e}'
repr(e)
到目前为止,它是唯一的解决方案,可帮助我在某些特定情况下针对我发现的错误至少打印最少的信息。repr(e)
产生KeyError(0,)
(这就是错误所在),分别是str(e)
或e.message
只产生0
或根本不产生任何结果。
我有同样的问题。我认为最好的解决方案是使用log.exception,它将自动打印出堆栈跟踪和错误消息,例如:
try:
pass
log.info('Success')
except:
log.exception('Failed')
log
啊 我刚import log
在Python 2.7.13上尝试过,并收到一条消息,提示没有模块具有该名称。是通过添加的内容pip
还是在较新版本的python中添加的内容(我知道,我知道,我需要更新至Python 3 ...我将在CentOS默认情况下停止随Python 2一起发货时这样做)。 ...)
import logging
\ nlog = logging.getLogger(__name__)
except Foo as bar:
相同except Foo, bar:
(除了前者是较新的东西,并且将继续在3.x中使用),无论错误是随message
属性带来的还是独立发生的。