无争议地提高

use*_*ica 21 python exception

没有参数的raise语句的文档

如果不存在表达式,则raise会重新引发当前作用域中处于活动状态的最后一个异常.

我曾经认为这意味着当前的函数必须执行一个except子句.在阅读了这个问题并进行了一些实验后,我认为这意味着堆栈上的任何函数都必须执行一个except子句,但我不确定.另外,我已经意识到我不知道堆栈跟踪如何与no-arg raise一起工作:

def f():
  try:
    raise Exception
  except:
    g()

def g():
  raise

f()
Run Code Online (Sandbox Code Playgroud)

产生

Traceback (most recent call last):
  File "foo", line 10, in <module>
    f()
  File "foo", line 5, in f
    g()
  File "foo", line 3, in f
    raise Exception
Exception
Run Code Online (Sandbox Code Playgroud)

这看起来不像初始加注时的堆栈,或者重新加注时的堆栈,或者两个堆栈的串联,或者我能理解的任何东西.

我是否正确寻找执行except子句的堆栈上的任何函数?此外,堆栈跟踪如何在重新加载时起作用?

Mar*_*ers 21

如果raise没有参数,解释器将查找引发和处理最后一个异常.然后它就像您使用最新的异常类型,值和回溯一样.raise

这存储在当前线程的解释器状态中,并且可以使用相同的信息来检索sys.exc_info().通过'处理'我的意思是一个except子句捕获了异常.引用try声明文档:

在执行except子句的套件之前,将有关异常的详细信息分配给sys模块中的三个变量:sys.exc_type接收标识异常的对象; sys.exc_value接收异常的参数; sys.exc_traceback接收一个回溯对象(参见标识程序中发生异常的点的标准类型层次结构.这些细节也可以通过sys.exc_info()函数获得,该函数返回一个元组(exc_type, exc_value, exc_traceback).

请参阅Python评估循环(C代码)中的实现说明,具体如下:

第二个项目符号是为了向后兼容:在捕获异常时调用一个函数并且让该函数通过sys.exc_ZZZ访问捕获的异常是常见的.(例如:traceback.print_exc()).

回溯反映了您如何准确地进行重新加注.它是当前堆栈(第10行调用f(),第5行调用g())加上引发的异常的原始位置:第3行.


use*_*ica 5

事实证明,Python 使用了一种令人惊讶的方式来构建回溯。Python不是在异常创建时(如 Java)或在引发异常时(如我以前认为的)构建整个堆栈跟踪,而是在异常冒泡时一次一帧地构建部分回溯。

每次异常冒泡到新的堆栈帧时,以及当异常以 的单参数形式raise(或双参数形式,在 Python 2 上)时,Python 字节码解释器循环执行PyTraceback_Here以添加新的前往表示堆栈跟踪的回溯对象的链接列表。(Python 2 上的0-argumentraise和 3-argument raise,跳过这一步。)

Python 维护一个每个线程的异常堆栈(和回溯),这些异常(和回溯)由尚未完成执行的exceptfinally块挂起。0 参数raise 恢复由该堆栈顶部条目表示的异常(和回溯),即使exceptorfinally位于不同的函数中。

f执行它raise

raise Exception
Run Code Online (Sandbox Code Playgroud)

Python 构建了一个对应于该行的回溯:

  File "foo", line 3, in f
    raise Exception
Run Code Online (Sandbox Code Playgroud)

g执行0-论点raise,这回溯被恢复,但没有条目被添加为0参数的raise线。

之后,当异常通过堆栈的其余部分向上冒泡时,g()f()调用的条目被添加到堆栈跟踪中,从而导致显示的最终堆栈跟踪:

Traceback (most recent call last):
  File "foo", line 10, in <module>
    f()
  File "foo", line 5, in f
    g()
  File "foo", line 3, in f
    raise Exception
Exception
Run Code Online (Sandbox Code Playgroud)