我会这样做,因此更改它的类型foo()
将不需要也将其更改bar()
。
def foo():
try:
raise IOError('Stuff')
except:
raise
def bar(arg1):
try:
foo()
except Exception as e:
raise type(e)(e.message + ' happens at %s' % arg1)
bar('arg1')
Traceback (most recent call last):
File "test.py", line 13, in <module>
bar('arg1')
File "test.py", line 11, in bar
raise type(e)(e.message + ' happens at %s' % arg1)
IOError: Stuff happens at arg1
更新1
这是保留原始回溯的略微修改:
...
def bar(arg1):
try:
foo()
except Exception as e:
import sys
raise type(e), type(e)(e.message +
' happens at %s' % arg1), sys.exc_info()[2]
bar('arg1')
Traceback (most recent call last):
File "test.py", line 16, in <module>
bar('arg1')
File "test.py", line 11, in bar
foo()
File "test.py", line 5, in foo
raise IOError('Stuff')
IOError: Stuff happens at arg1
更新2
对于Python 3.x,我的第一次更新中的代码在语法上是不正确的,并且在message
2012 BaseException
年5 月16日对PEP 352的更改中收回了启用属性的想法(我的第一次更新发布于2012-03-12) 。因此,当前,无论如何,在Python 3.5.2中,您都需要按照以下步骤做一些事情以保留回溯,而不是硬编码function中的异常类型bar()
。另请注意,将出现以下行:
During handling of the above exception, another exception occurred:
在显示的回溯消息中。
# for Python 3.x
...
def bar(arg1):
try:
foo()
except Exception as e:
import sys
raise type(e)(str(e) +
' happens at %s' % arg1).with_traceback(sys.exc_info()[2])
bar('arg1')
更新3
一个评论者询问是否有会在两个Python 2和3。工作虽然答案可能似乎是“不”,因为语法不同的方式,还有就是周围的一种方法,通过使用一个辅助函数一样reraise()
在six
添加-在模块上。因此,如果您出于某种原因不愿使用该库,则下面是简化的独立版本。
还要注意,由于异常是在reraise()
函数中引发的,因此它将在引发任何回溯的情况下出现,但最终结果是您想要的。
import sys
if sys.version_info.major < 3: # Python 2?
# Using exec avoids a SyntaxError in Python 3.
exec("""def reraise(exc_type, exc_value, exc_traceback=None):
raise exc_type, exc_value, exc_traceback""")
else:
def reraise(exc_type, exc_value, exc_traceback=None):
if exc_value is None:
exc_value = exc_type()
if exc_value.__traceback__ is not exc_traceback:
raise exc_value.with_traceback(exc_traceback)
raise exc_value
def foo():
try:
raise IOError('Stuff')
except:
raise
def bar(arg1):
try:
foo()
except Exception as e:
reraise(type(e), type(e)(str(e) +
' happens at %s' % arg1), sys.exc_info()[2])
bar('arg1')
message
属性的文档时,我发现了这个问题,Python 2.6中不推荐使用BaseException.message,这似乎表明现在不鼓励使用它(以及为什么不在文档中)。