在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')创建一个异常对象,但是从不实际引发异常是完全合法的(尽管通常是毫无意义的)。

无论如何,从您的问题中并不清楚您要在这里实现什么。如果您对此进行说明,将会有所帮助。

10-06 00:55