我的背景是在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)
这包括消息和两个回溯,但它不会显示回溯中发生的异常.
是否有在Python中使用异常链的标准方法?像Java引起的'异常'一样?
这是一些背景知识.
我有一个带有一个主要异常类的模块DSError:
class DSError(Exception):
pass
Run Code Online (Sandbox Code Playgroud)
在这个模块的某个地方会有:
try:
v = my_dict[k]
something(v)
except KeyError as e:
raise DSError("no key %s found for %s" % (k, self))
except ValueError as e:
raise DSError("Bad Value %s found for %s" % (v, self))
except DSError as e:
raise DSError("%s raised in %s" % (e, self))
Run Code Online (Sandbox Code Playgroud)
基本上这个片段应该只抛出DSError并告诉我发生了什么以及为什么.问题是try块可能会抛出很多其他异常,所以我更喜欢我能做的事情如下:
try:
v = my_dict[k]
something(v)
except Exception as e:
raise DSError(self, v, e) # Exception chained...
Run Code Online (Sandbox Code Playgroud)
这是标准的pythonic方式吗?我没有在其他模块中看到异常链,那么在Python中如何完成?
这是Debian Squeeze上的Python 2.6.6(默认).请考虑以下Python代码.
import sys
try:
raise Exception("error in main")
pass
except:
exc_info = sys.exc_info()
finally:
try:
print "cleanup - always run"
raise Exception("error in cleanup")
except:
import traceback
print >> sys.stderr, "Error in cleanup"
traceback.print_exc()
if 'exc_info' in locals():
raise exc_info[0], exc_info[1], exc_info[2]
print "exited normally"
Run Code Online (Sandbox Code Playgroud)
获得的错误是
Error in cleanup
Traceback (most recent call last):
File "<stdin>", line 10, in <module>
Exception: error in cleanup
cleanup - always run
Traceback (most recent call last):
File "<stdin>", line 3, in …Run Code Online (Sandbox Code Playgroud) 这是什么raise做的,如果它不是内部try或except条款,而只是作为函数的最后一条语句?
def foo(self):
try:
# some code that raises an exception
except Exception as e:
pass
# notice that the "raise" is outside
raise
Run Code Online (Sandbox Code Playgroud)
此示例打印1,但不打印2,因此必须是last raise语句只是引发了最后抛出的异常。
def foo():
try:
raise Exception()
except Exception as e:
pass
print 1
raise
print 2
if __name__ == '__main__':
foo()
Run Code Online (Sandbox Code Playgroud)
有关这种使用方式的任何正式文档?