在python(v2.7.3)中使用自定义异常:调用getSub()时不要获得堆栈跟踪,而getSub(True)调用一个,不同之处在于它是通过额外的尝试引起的......除了我想避免(+感觉不必要),为什么/如何避免?
import sys, traceback
class customException(Exception):
def __init__(self, *args):
super(customException,self).__init__(*args)
print "Stack trace within exception", traceback.extract_tb(sys.exc_info()[2])
errTxt = [a for a in args]
print "error text", errTxt
def getFn():
try:
getSub()
except customException as e:
print "customException was raised"
try:
getSub(True)
except customException as e:
print "customException2 was raised"
def getSub(flag=False):
if flag:
try:
1/0
except:
raise customException('test')
else:
raise customException('test')
getFn()
输出:
Stack trace within exception []
error text ['test']
customException was raised
Stack trace within exception [('./test3.py', 25, 'getSub', '1/0')]
error text ['test']
customException2 was raised
要把上面的内容放在上下文中,我在下面的行中有代码(伪),直到我将代码归结为上面的例子,我才意识到为什么回溯访问并不总是有效。自定义异常类的目的是收集异常的聚合计数,以便在下游对每个do_something的结果进行分类,例如:使用回溯是从WHERE记录异常被“引发”,因此创建异常(1/0 =虽然看起来不合适)使其能够工作。想知道如何使用检查模块而不是在回溯堆栈中考虑这个问题?
__main__
With each item in set:
Try:
do_something(item)
except customException()
clean up = log info etc.
end With
end.__main__
do_something(item)
try:
check_something()
except customException
if exception=typeA.1 raise customException(Type1)
if exception=typeB.2 and item = ‘x’
raise customException(Type2)
check_something()
a = getInfo()
unless getInfo()
raise customException(typeA.1)
try:
b = getOtherInfo()
except customException
raise customException(typeB.2)
…
答案 0 :(得分:3)
如果我理解你的话,你会想知道为什么你的print "Stack trace within exception"
行会打印getSub()
的空列表,但会为getSub(True)
打印一些追溯信息。
您的例外类__init__
中有代码可通过sys.exc_info
查看最新的异常。执行raise customException('test')
时,customException('test')
首先自行评估,然后才“知道”它将作为异常引发。因此,当你在getSub()
中进行加注时,没有最近的异常。
使用getSub(True)
时,会出现最新的异常,因为1/0
会在创建customException之前引发异常。请注意,当您执行1/0时,最新的异常是来自该1/0的异常;你可以看到回溯中没有关于你的customException。
必须在引发异常之前创建异常对象。因此,您无法在异常类的__init__
中查看“当前异常”,以获取有关在引发时将创建的堆栈跟踪的信息,因为它尚未被创建当时还是提出来了。
如果需要,可以在创建异常对象时使用traceback.extract_stack
来获取调用堆栈,但不能保证在引发异常对象时它与之有任何关系。仅仅因为创建了一个异常类的实例,甚至根本不会意味着它会被提升。对于某人来说,使用stuff = customException('blah')
创建一个异常对象但从未真正提出异常,这是完全合法的(尽管通常毫无意义)。
无论如何,你的问题并不清楚你在这里想要达到的目的。如果你解释了它会有所帮助。
答案 1 :(得分:0)
因为您正在捕获异常,所以除非您明确重新提升
,否则不会有回溯try:
getSub(True)
except customException as e:
print "customException2 was raised"
raise # add this to re-raise, with original traceback
或自己打印:
try:
getSub(True)
except customException as e:
print "customException2 was raised"
print traceback.format_exc()