首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >"raise“和"raise e”的区别?

"raise“和"raise e”的区别?
EN

Stack Overflow用户
提问于 2016-03-22 19:57:46
回答 3查看 12.5K关注 0票数 26

在python中,except块中的raiseraise e有区别吗?

dis向我展示了不同的结果,但我不知道它是什么意思。

两者的最终行为是什么?

代码语言:javascript
复制
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        
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-03-22 20:04:36

在这种情况下没有区别。不带参数的raise will always raise the last exception thrown (也可以通过sys.exc_info()访问)。

字节码不同的原因是因为Python是一种动态语言,而解释器并不真正“知道”e指的是当前正在处理的(未修改的)异常。但情况可能并不总是这样,请考虑:

代码语言:javascript
复制
try:
    raise Exception()
except Exception as e:
    if foo():
        e = OtherException()
    raise e

e现在是什么?没有办法知道何时编译字节码(只有在实际运行程序时)。

在像您这样的简单示例中,Python解释器可能会“优化”字节码,但到目前为止还没有人这样做。他们为什么要这么做呢?这充其量是一个微优化,在模糊的条件下仍然可能以微妙的方式中断。还有很多其他水果挂在比这个更低的位置,而且更有营养;-)

票数 26
EN

Stack Overflow用户

发布于 2017-09-01 01:15:32

这两种形式生成的回溯是不同的。

使用raise,这段代码如下:

代码语言:javascript
复制
try:
   int("hello")
except ValueError as e:
   raise

提供以下回溯:

代码语言:javascript
复制
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

代码语言:javascript
复制
try:
   int("hello")
except ValueError as e:
   raise e

给出以下回溯

代码语言:javascript
复制
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

票数 28
EN

Stack Overflow用户

发布于 2016-03-28 01:14:30

可以使用sys.exc_clear()清除“最后一个异常”(即sys.exc_info()的结果)信息。例如,如果catch块调用函数foo(),就会发生这种情况,该函数本身具有特殊的错误处理。

在这种情况下,带参数和不带参数的raise意味着不同的事情。raise e仍然有对上面几行捕获的异常的引用,而raise速记将尝试引发None,这是一个错误。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36153805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档