我的背景是在C#中,我刚刚开始用Python编程.抛出异常时,我通常希望将其包装在另一个添加更多信息的异常中,同时仍然显示完整的堆栈跟踪.在C#中它很容易,但我如何在Python中完成它?
例如.在C#我会做这样的事情:
try
{
ProcessFile(filePath);
}
catch (Exception ex)
{
throw new ApplicationException("Failed to process file " + filePath, ex);
}
Run Code Online (Sandbox Code Playgroud)
在Python中我可以做类似的事情:
try:
ProcessFile(filePath)
except Exception as e:
raise Exception('Failed to process file ' + filePath, e)
Run Code Online (Sandbox Code Playgroud)
......但这会失去内部异常的追溯!
编辑:我想看到两个异常消息和两个堆栈跟踪并将两者关联起来.也就是说,我想在输出中看到异常X在这里发生,然后异常Y在那里 - 就像在C#中一样.这在Python 2.6中是否可行?看起来我能做到的最好(根据Glenn Maynard的回答)是:
try:
ProcessFile(filePath)
except Exception as e:
raise Exception('Failed to process file' + filePath, e), None, sys.exc_info()[2]
Run Code Online (Sandbox Code Playgroud)
这包括消息和两个回溯,但它不会显示回溯中发生的异常.
以下是我在Doug Hellman网站上发现的一个名为"masking_exceptions_catch.py"的文件中的示例.我暂时无法找到该链接.抛出throws()中引发的异常,同时报告由cleanup()引发的异常.
在他的文章中,Doug评论说处理是非直观的.中途期望它是Python版本中的一个bug或限制(大约在2009年),我在Mac的当前生产版本中运行它(2.7.6).它仍然报告cleanup()的异常.我发现这有点惊人,并希望看到它是如何实际正确或理想的行为的描述.
#!/usr/bin/env python
import sys
import traceback
def throws():
raise RuntimeError('error from throws')
def nested():
try:
throws()
except:
try:
cleanup()
except:
pass # ignore errors in cleanup
raise # we want to re-raise the original error
def cleanup():
raise RuntimeError('error from cleanup')
def main():
try:
nested()
return 0
except Exception, err:
traceback.print_exc()
return 1
if __name__ == '__main__':
sys.exit(main())
Run Code Online (Sandbox Code Playgroud)
节目输出:
$ python masking_exceptions_catch.py
Traceback (most recent call last):
File "masking_exceptions_catch.py", line 24, in main
nested()
File "masking_exceptions_catch.py", line …
Run Code Online (Sandbox Code Playgroud) 我相信你发现自己处于这种情况,我怀疑没有办法摆脱这种情况。假设您运行了一些引发异常的 python 代码,然后您想查看它,但在这样做时不小心引发了另一个异常。如果您现在尝试事后调试,您将看到后一个异常的回溯。我的问题是,前者会永远消失吗?
例子:
def my_buggy_function(x):
y = x + 1
raise RuntimeError
Run Code Online (Sandbox Code Playgroud)
第 1 步:我提出了一个错误,我想对其进行调试
my_buggy_function(1)
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
/home/user/<ipython-input-1-430423eaff77> in <module>()
3 raise RuntimeError
4
----> 5 my_buggy_function(1)
/home/user/<ipython-input-1-430423eaff77> in my_buggy_function(x)
1 def my_buggy_function(x):
2 y = x + 1
----> 3 raise RuntimeError
4
5 my_buggy_function(1)
RuntimeError:
Run Code Online (Sandbox Code Playgroud)
第 2 步:我尝试调试错误但不小心引发了另一个错误(在这种情况下,我没有加载 pdb)
pdb.pm() #Oops..
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/home/user/<ipython-input-2-619d77b83f20> in <module>()
----> 1 pdb.pm()
NameError: name 'pdb' is not …
Run Code Online (Sandbox Code Playgroud)