在python中,except块中的raise和raise e有区别吗?
dis向我展示了不同的结果,但我不知道它是什么意思。
两者的最终行为是什么?
import dis
def a():
try:
raise Exception()
except Exception as e:
raise
def b():
try:
raise Exception()
except Exception as e:
raise e
dis.dis(a)
# OUT: 4 0 SETUP_EXCEPT 13 (to 16)
# OUT: 5 3 LOAD_GLOBAL 0 (Exception)
# OUT: 6 CALL_FUNCTION 0
# OUT: 9 RAISE_VARARGS 1
# OUT: 12 POP_BLOCK
# OUT: 13 JUMP_FORWARD 22 (to 38)
# OUT: 6 >> 16 DUP_TOP
# OUT: 17 LOAD_GLOBAL 0 (Exception)
# OUT: 20 COMPARE_OP 10 (exception match)
# OUT: 23 POP_JUMP_IF_FALSE 37
# OUT: 26 POP_TOP
# OUT: 27 STORE_FAST 0 (e)
# OUT: 30 POP_TOP
# OUT: 7 31 RAISE_VARARGS 0
# OUT: 34 JUMP_FORWARD 1 (to 38)
# OUT: >> 37 END_FINALLY
# OUT: >> 38 LOAD_CONST 0 (None)
# OUT: 41 RETURN_VALUE
dis.dis(b)
# OUT: 4 0 SETUP_EXCEPT 13 (to 16)
# OUT: 5 3 LOAD_GLOBAL 0 (Exception)
# OUT: 6 CALL_FUNCTION 0
# OUT: 9 RAISE_VARARGS 1
# OUT: 12 POP_BLOCK
# OUT: 13 JUMP_FORWARD 25 (to 41)
# OUT: 6 >> 16 DUP_TOP
# OUT: 17 LOAD_GLOBAL 0 (Exception)
# OUT: 20 COMPARE_OP 10 (exception match)
# OUT: 23 POP_JUMP_IF_FALSE 40
# OUT: 26 POP_TOP
# OUT: 27 STORE_FAST 0 (e)
# OUT: 30 POP_TOP
# OUT: 7 31 LOAD_FAST 0 (e)
# OUT: 34 RAISE_VARARGS 1
# OUT: 37 JUMP_FORWARD 1 (to 41)
# OUT: >> 40 END_FINALLY
# OUT: >> 41 LOAD_CONST 0 (None)
# OUT: 44 RETURN_VALUE 发布于 2016-03-22 20:04:36
在这种情况下没有区别。不带参数的raise will always raise the last exception thrown (也可以通过sys.exc_info()访问)。
字节码不同的原因是因为Python是一种动态语言,而解释器并不真正“知道”e指的是当前正在处理的(未修改的)异常。但情况可能并不总是这样,请考虑:
try:
raise Exception()
except Exception as e:
if foo():
e = OtherException()
raise ee现在是什么?没有办法知道何时编译字节码(只有在实际运行程序时)。
在像您这样的简单示例中,Python解释器可能会“优化”字节码,但到目前为止还没有人这样做。他们为什么要这么做呢?这充其量是一个微优化,在模糊的条件下仍然可能以微妙的方式中断。还有很多其他水果挂在比这个更低的位置,而且更有营养;-)
发布于 2017-09-01 01:15:32
这两种形式生成的回溯是不同的。
使用raise,这段代码如下:
try:
int("hello")
except ValueError as e:
raise提供以下回溯:
Traceback (most recent call last):
File "myfile.py", line 2, in <module>
int("hello")
ValueError: invalid literal for int() with base 10: 'hello'按如下方式使用raise e:
try:
int("hello")
except ValueError as e:
raise e给出以下回溯
Traceback (most recent call last):
File "myfile.py", line 4, in <module>
raise e
ValueError: invalid literal for int() with base 10: 'hello'不同之处在于,在raise情况下,回溯中引用了引用异常原始源的正确行,但在raise e情况下,回溯引用的是raise e行,而不是原始原因。
因此,我建议始终使用raise而不是raise e。
发布于 2016-03-28 01:14:30
可以使用sys.exc_clear()清除“最后一个异常”(即sys.exc_info()的结果)信息。例如,如果catch块调用函数foo(),就会发生这种情况,该函数本身具有特殊的错误处理。
在这种情况下,带参数和不带参数的raise意味着不同的事情。raise e仍然有对上面几行捕获的异常的引用,而raise速记将尝试引发None,这是一个错误。
https://stackoverflow.com/questions/36153805
复制相似问题