如何检查,当前范围内是否出现异常?

2024-10-04 05:23:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用以下代码调用具有适当数量参数的任意可调用f()

try:
    res = f(arg1)
except TypeError:
    res = f(arg1, arg2)

如果f()是一个双参数函数,则仅用一个参数调用它会引发TypeError,因此可以在except分支中正确调用该函数。你知道吗

问题是当f()是一个参数函数,并且在f()的主体中出现异常时(可能是因为对某个函数的错误调用),例如:

def f(arg):
    map(arg) # raises TypeError

由于f()的内部错误,控制流转到except分支。当然,用两个参数调用f()会产生一个新的TypeError。然后我用两个参数回溯到f()的调用,而不是回溯到原始错误,这在调试时没有多大帮助。你知道吗

我的代码如何识别不在当前范围内引发的异常以重新激活它们?你知道吗

我想这样写代码:

try:
    res = f(arg1)
except TypeError:
    if exceptionRaisedNotInTheTryBlockScope(): # <-- subject of the question
        raise
    res = f(arg1, arg2)

我知道我可以通过在except块中添加exc_info = sys.exc_info()来使用walkarround。你知道吗

其中一个假设是我无法控制f(),因为它是由模块的用户提供的。它的__name__属性也可以不是'f'。对f()的错误循环调用可能引发内部异常。 walkarround不合适,因为它使f()作者的调试复杂化。你知道吗


Tags: 函数代码info参数错误分支argres
2条回答

您可以捕获异常对象并检查它。你知道吗

try:
    res = f(arg1)
except TypeError as e:
    if "f() missing 1 required positional argument" in e.args[0]: 
        res = f(arg1, arg2)
    else:
        raise

不过,坦白地说,如果在f()调试中产生的错误不成问题,那么不使用额外的长度来分类异常应该可以很好地工作,因为您应该同时获得原始回溯和辅助回溯。你知道吗

此外,如果您可以控制f(),则可以将第二个参数设为可选参数,而不必进行二次猜测:

def f(a, b=None):
    pass

现在你可以随便说了。你知道吗

这个怎么样:

import inspect

if len(inspect.getargspec(f).args) == 1:
    res = f(arg1)
else:
    res = f(arg1, arg2)

终于想明白了:

def exceptionRaisedNotInTheTryBlockScope():
    return sys.exc_info()[2].tb_next is not None

sys.exc_info()返回一个3元素tuple。它的最后一个元素是最后一个异常的回溯。如果回溯对象是回溯链中的唯一对象,那么在try块(https://docs.python.org/2/reference/datamodel.html)的范围内出现了异常。你知道吗

根据https://docs.python.org/2/library/sys.html#sys.exc_info,应该避免存储回溯值。你知道吗

相关问题 更多 >