基金e和c的区别:“提高”和“提高e”之间的区别(difference between rise and raise)

关于基金e和c的区别的问题,在difference between rise and raise中经常遇到, 在 python 中,除了块中的raise和raise e之间有区别吗?

在 python 中,除了块中的raiseraise 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        
33

两种形式生成的回溯存在差异。

使用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

26

在这种情况下没有区别。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 e

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

在像你这样的简单例子中,Python 解释器可能会“优化”字节码,但到目前为止还没有人这样做。他们为什么要这样做?它充其量是一个微观优化,在晦涩的条件下仍可能以微妙的方式中断。

2

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

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

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(492)
Posit on:ggplot2:stat_summary与geom_boxplot的水平位置
上一篇
Apt编程:# apt-get……与sudo apt-get的意思相同
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(62条)