在python(v2.7.3)中使用自定义异常:在调用getSub()时不会获得堆栈跟踪,而getSub(True)会调用一个,不同之处在于它是通过额外的try引起的...避免(+不必要),为什么/如何避免呢?
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的结果进行下游分类,例如致命事件,警告等。使用回溯记录是从哪里记录了“引发”异常,因此创建异常(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)
…
最佳答案
如果我理解正确,您想知道为什么您的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')
创建一个异常对象,但是从不实际引发异常是完全合法的(尽管通常是毫无意义的)。
无论如何,从您的问题中并不清楚您要在这里实现什么。如果您对此进行说明,将会有所帮助。