没有参数的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行.
事实证明,Python 使用了一种令人惊讶的方式来构建回溯。Python不是在异常创建时(如 Java)或在引发异常时(如我以前认为的)构建整个堆栈跟踪,而是在异常冒泡时一次一帧地构建部分回溯。
每次异常冒泡到新的堆栈帧时,以及当异常以 的单参数形式raise(或双参数形式,在 Python 2 上)时,Python 字节码解释器循环执行PyTraceback_Here以添加新的前往表示堆栈跟踪的回溯对象的链接列表。(Python 2 上的0-argumentraise和 3-argument raise,跳过这一步。)
Python 维护一个每个线程的异常堆栈(和回溯),这些异常(和回溯)由尚未完成执行的except和finally块挂起。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)
| 归档时间: |
|
| 查看次数: |
9002 次 |
| 最近记录: |