我想达到这样的效果:
def foo():
try:
raise IOError('Stuff ')
except:
raise
def bar(arg1):
try:
foo()
except Exception as e:
e.message = e.message + 'happens at %s' % arg1
raise
bar('arg1')
Traceback...
IOError('Stuff Happens at arg1')
但我得到的是:
Traceback..
IOError('Stuff')
关于如何实现这一点,有什么线索吗?如何在Python 2和3中都做到这一点?
到目前为止,我对所有给出的答案都不满意。他们还是太啰嗦了。在代码和消息输出中。
所有我想要的是stacktrace指向源异常,没有异常之间的东西,所以没有创建新的异常,只是重新提升原始与所有相关的堆栈帧状态在它,导致那里。
史蒂夫·霍华德给出了一个很好的答案,我想扩展一下,不,是简化一下……仅适用于python 3。
except Exception as e:
e.args = ("Some failure state", *e.args)
raise
唯一的新东西是参数展开/解包,这使得它对我来说足够小和容易使用。
试一试:
foo = None
try:
try:
state = "bar"
foo.append(state)
except Exception as e:
e.args = ("Appending '"+state+"' failed", *e.args)
raise
print(foo[0]) # would raise too
except Exception as e:
e.args = ("print(foo) failed: " + str(foo), *e.args)
raise
这将给你:
Traceback (most recent call last):
File "test.py", line 6, in <module>
foo.append(state)
AttributeError: ('print(foo) failed: None', "Appending 'bar' failed", "'NoneType' object has no attribute 'append'")
简单的漂亮图案可以是这样的
print("\n".join( "-"*i+" "+j for i,j in enumerate(e.args)))
在PEP 678中,本机支持向异常添加注释:
try:
raise TypeError('bad type')
except Exception as e:
e.add_note('Add some information')
raise
呈现为:
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: bad type
Add some information
我跳它可以取代史蒂夫霍华德的解决方案,不幸的是,它不给用户任何控制如何格式化最终的异常(例如,不能在异常之前添加一个注释,如:'错误在fn: {original_exc}')
如果想要对回溯进行更多控制,可以使用https://github.com/google/etils:
from etils import epy
with epy.maybe_reraise('Error in fn: '):
fn()
Or:
try:
fn()
except Exception as e:
epy.reraise(e, suffix='. Did you mean y ?')