在异常中将信息传递到堆栈中吗?

时间:2019-06-11 08:42:06

标签: python exception

在长时间运行的函数中,某些循环中出现了异常。如果发生异常,我想记录发生异常的循环中位于索引处的内容。不幸的是,我所需的信息在当前函数中不可用,而是在堆栈中的下一个函数中。但是,索引在堆栈中的下一个函数中不可用,仅在当前函数中可用。因此,为了记录适当的信息,我需要来自两个处于不同嵌套级别的函数调用的信息。如何在Exception中的函数之间传递信息?

例如:

def foo():
    information_I_need = ["some", "arbitrary", "things"]
    data_operated_on = list(range(0, 10*len(information_I_need), 10)) #0,10,20
    #NB: these two lists are the same size
    try:
        bar(data_operated_on)
    except ValueError as e:
        i = e.get_the_index_where_bar_failed()
        print(information_I_need[i])

def bar(aoi):
    for i in range(len(aoi)):
        try:
            fails_on_10(aoi[i])
        except ValueError as e:
            e.add_the_index_where_bar_failed(i)
            raise e

def fails_on_10(n):
    if n == 10:
        raise ValueError("10 is the worst!")

这里的预期行为是调用foo()会打印"arbitrary"

在此示例中,bar具有i正确报告问题所需的信息(即索引foo)。如何从barfoo那里获取信息?

1 个答案:

答案 0 :(得分:3)

您可以将索引添加为异常对象的属性。

最好使用自定义异常类来执行此操作,而不是使用内置异常之一。

class BadInformation(Exception):
    def __init__(self, message, index):
        # py2/3 compat
        # if only targeting py3 you can just use super().__init__(message)
        super(BadInformation, self).__init__(message)
        self.bad_index = index

def foo():
    information_I_need = ["some", "arbitrary", "things"]
    data_operated_on = list(range(0, 10*len(information_I_need), 10)) #0,10,20
    #NB: these two lists are the same size
    try:
        bar(data_operated_on)
    except BadInformation as e:
        i = e.bad_index
        print(information_I_need[i])

def bar(aoi):
    # if you need both the index and value, use `enumerate()`
    for index, value in enumerate(aoi):
        try:
            fails_on_10(value)
        except ValueError as e:
            raise BadInformation(str(e), index)
            ## on py 3 you may want this instead
            ## to keep the full traceback
            # raise BadInformation(str(e), index) from e



def fails_on_10(n):
    if n == 10:
        raise ValueError("10 is the worst!")