从调用者的范围中提出异常?

时间:2013-06-20 20:30:47

标签: python exception-handling error-handling

假设我有以下脚本:

def do_not_call_on_one(i):
    if i == 1:
        raise ValueError("You never listen.")

    print "Success!"

do_not_call_on_one(1)

在执行时,您将看到以下追溯:

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    do_not_call_on_one(1)
  File "test.py", line 3, in do_not_call_on_one
    raise ValueError("You never listen.")
ValueError: You never listen.

有没有办法操纵调用堆栈,以便从实际导致问题的行发出错误,如此?:

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    do_not_call_on_one(1)
ValueError: You never listen.

如果可以提前定义正确的行为,这将节省开发人员的时间,否则会浪费扫描调用堆栈,搜索错误使用的函数。

Python中是否有允许异常使用修改后的回溯的内容?

更新

有些buitins正在复制此功能:

# In test.py:
int('a')

# Executing 'python test.py' yields:
Traceback (most recent call last):
  File "test.py", line 1, in <module>
    int('a')
ValueError: invalid literal for int() with base 10: 'a'

注意:回溯不会进入int()函数,以显示一堆无用的范围(尤其是无用的raise ValueError本身)。

2 个答案:

答案 0 :(得分:3)

tl; dr:可能是的,但我无法想象这是一个好主意。

我会假设,如果我们努力的话,我们可以假装一个callstack来显示来自不同地方的异常。但我认为这不是一个好主意。

首先,人们普遍认为引发异常的功能并不总是错误的。如果有人违反合同并向你传递了一个你不期望的参数,那么可以提出异常。如果这是为了通过提高呼叫者范围内的例外来覆盖你的屁股,所以没有人责怪你的功能,我认为有人(也许你,也许你的自动化测试的“责备”系统)需要重新思考他们如何确定责任。 / p>

第二,我认为你不能很好地定义“正确”的范围。您可能会想到应该始终在调用者的范围内提出它,因为显然它不是您的错误。好吧,如果它不是他们的错误怎么办?当异常发生时,每个功能是否只是举起手来说“不是我的错”?很快我们的堆栈跟踪就什么都不说了。

即使你是对的,你的功能也是无可指责的,你也要把别人的生命变成地狱,因为操纵罢工堆来隐藏你的功能会让每个人都抓不到头脑,并删除有价值的证据来调试情况

这看起来似乎是一个好主意,但我认为不是这样,而且我认为如果你把自己放在别人的鞋子里,你就会明白,如果尝试使用一个表现出来的功能会让他们的生活变得多么困难方式。

答案 1 :(得分:1)

我建议在你希望位于调用堆栈顶部的位置捕获异常,然后引发一个包含旧异常的新异常(这样你就可以引用原始调用堆栈来知道实际导致的异常问题;毕竟,当print "Success!"失败时会发生什么,因为有人设置sys.stdout = int?)。


经过一番浏览后,似乎https://stackoverflow.com/a/2615442/138772正是您想要的那种答案。