- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
以下是我在 Doug Hellman 网站上在名为“masking_exceptions_catch.py”的文件中找到的示例。我暂时找不到链接。 throws() 引发的异常被丢弃,而 cleanup() 引发的异常被报告。
在他的文章中,Doug 评论说处理是不直观的。在编写它时(大约 2009 年),我认为它是 Python 版本中的一个错误或限制,我在当前的 Mac 版 Python (2.7.6) 中运行了它。它仍然报告来自 cleanup() 的异常。我觉得这有点令人惊讶,并希望看到它实际上是如何正确或理想的行为的描述。
#!/usr/bin/env python
import sys
import traceback
def throws():
raise RuntimeError('error from throws')
def nested():
try:
throws()
except:
try:
cleanup()
except:
pass # ignore errors in cleanup
raise # we want to re-raise the original error
def cleanup():
raise RuntimeError('error from cleanup')
def main():
try:
nested()
return 0
except Exception, err:
traceback.print_exc()
return 1
if __name__ == '__main__':
sys.exit(main())
$ python masking_exceptions_catch.py
Traceback (most recent call last):
File "masking_exceptions_catch.py", line 24, in main
nested()
File "masking_exceptions_catch.py", line 14, in nested
cleanup()
File "masking_exceptions_catch.py", line 20, in cleanup
raise RuntimeError('error from cleanup')
RuntimeError: error from cleanup
最佳答案
回过头来回答。我先不回答你的问题。 :-)
这真的有效吗?
def f():
try:
raise Exception('bananas!')
except:
pass
raise
# python 3.3
4 except:
5 pass
----> 6 raise
7
RuntimeError: No active exception to reraise
# python 2.7
1 def f():
2 try:
----> 3 raise Exception('bananas!')
4 except:
5 pass
Exception: bananas!
def f():
try:
raise Exception('bananas!')
except Exception as e:
pass
raise e
# python 3.3
4 except Exception as e:
5 pass
----> 6 raise e
7
UnboundLocalError: local variable 'e' referenced before assignment
# python 2.7
4 except Exception as e:
5 pass
----> 6 raise e
7
Exception: bananas!
try:
1/0
except Exception as e:
x=4
#can I access `x` here after the exception block? How about `e`?
try
和
except
不是范围。实际上,python 中很少有东西;我们有“LEGB 规则”来记住四个命名空间——本地、封闭、全局、内置。其他块根本不是作用域;我可以愉快地声明
x
内
for
循环并期望在该循环之后仍然能够引用它。
raise
是您最初询问的问题,这些问题密切相关,但实际上并不相同。 Python 3 可能会强制命名异常的范围仅限于它们的块,而无需解决裸
raise
事物。
raise
做‽
raise
作为保留堆栈跟踪的一种手段。 catch ,做记录/清理,再加注。很酷,我的清理代码没有出现在回溯中,99.9% 的时间有效。但是当我们尝试在异常处理程序中处理嵌套异常时,事情可能会变糟。有时。 (有关何时/不是问题,请参见底部的示例)
raise
将正确处理嵌套的异常处理程序,并找出正确的“当前”异常以重新引发。但这并不完全是现实。原来 - 在这里进入实现细节 - 异常信息被保存为当前
frame object 的成员.在 python 2 中,根本没有管道来处理单个帧内堆栈上的推送/弹出异常处理程序;只是一个包含最后一个异常的字段,而不管我们可能对其进行了任何处理。这就是裸
raise
抢。
6.9. The raise statement
raise_stmt ::= "raise" [expression ["," expression ["," expression]]]
If no expressions are present, raise re-raises the last exception that was active in the current scope.
raise
重新提出当前框架认为是“最后一个”异常的异常,这不一定是我们人类大脑认为特定于我们当时所处的词法嵌套异常块的异常。呸,瞄准镜!
RuntimeError: error from cleanup
,您的示例代码引发
RuntimeError: error from throws
正如预期的那样。
sys.exc_info
的语义),这通常是一个很好的理由不在一个小版本。
nested
功能变为:
def nested():
try:
throws()
except BaseException as e:
try:
cleanup()
except:
pass
raise e
Traceback (most recent call last):
File "example", line 24, in main
nested()
File "example", line 17, in nested
raise e
RuntimeError: error from throws
raise
的 3 参数版本.很多人不知道这个,它是一种合法(如果笨重)的方式来保留您的堆栈跟踪。
def nested():
try:
throws()
except:
e = sys.exc_info()
try:
cleanup()
except:
pass
raise e[0],e[1],e[2]
sys.exc_info
给了我们一个包含 (type, value, traceback) 的 3 元组,这正是
raise
的 3 参数版本需要。请注意,此 3-arg 语法仅适用于 python 2。
try/except
出
nested
并转化为自己的功能。
def nested():
try:
throws()
except:
cleanup()
raise
def cleanup():
try:
cleanup_code_that_totally_could_raise_an_exception()
except:
pass
def cleanup_code_that_totally_could_raise_an_exception():
raise RuntimeError('error from cleanup')
nested
的范围,它不会干扰您打算重新加注的异常。
raise
就像你在阅读所有这些并接受它之前所做的那样;清理代码通常不会引发异常,对吗? :-)
关于python - 当前异常上下文掩盖了先前的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23707530/
问题很简单:我正在寻找一种优雅的使用方式 CompletableFuture#exceptionally与 CompletableFuture#supplyAsync 一起.这是行不通的: priva
对于 Web 服务,我们通常使用 maven-jaxb2-plugin 生成 java bean,并在 Spring 中使用 JAXB2 编码。我想知道如何处理 WSDL/XSD 中声明的(SOAP-
这个问题已经有答案了: Array index out of bound behavior (10 个回答) 已关闭 8 年前。 我对下面的 C 代码感到好奇 int main(){
当在类的开头使用上下文和资源初始化 MediaPlayer 对象时,它会抛出 NullPointer 异常,但是当在类的开头声明它时(因此它是 null),然后以相同的方式初始化它在onCreate方
嘿 我尝试将 java 程序连接到 REST API。 使用相同的代码部分,我在 Java 6 中遇到了 Java 异常,并且在 Java 8 中运行良好。 环境相同: 信任 机器 unix 用户 代
我正在尝试使用 Flume 和 Hive 进行 Twitter 分析。为了从 twitter 获取推文,我在 flume.conf 文件中设置了所有必需的参数(consumerKey、consumer
我在 JavaFX 异常方面遇到一些问题。我的项目在我的 Eclipse 中运行,但现在我的 friend 也尝试访问该项目。我们已共享并直接保存到保管箱文件夹中。但他根本无法让它发挥作用。他在控制台
假设我使用 blur() 事件验证了电子邮件 ID,我正在这样做: $('#email').blur(function(){ //make ajax call , check if dupli
我这样做是为了从 C 代码调用非托管函数。 pCallback 是一个函数指针,因此在托管端是一个委托(delegate)。 [DllImport("MyDLL.dll")] public stati
为什么这段代码是正确的: try { } catch(ArrayOutOfBoundsException e) {} 这是错误的: try { } catch(IOException e) {} 这段
我遇到了以下问题:有导出函数的DLL。 代码示例如下:[动态链接库] __declspec(dllexport) int openDevice(int,void**) [应用] 开发者.h: __de
从其他线程,我知道我们不应该在析构函数中抛出异常!但是对于下面的例子,它确实有效。这是否意味着我们只能在一个实例的析构函数中抛出异常?我们应该如何理解这个代码示例! #include using n
为什么需要异常 引出 public static void main(String[
1. Java的异常机制 Throwable类是Java异常类型的顶层父类,一个对象只有是 Throwable 类的(直接或者间接)实例,他才是一个异常对象,才能被异常处理机制识别。JDK中内
我是 Python 的新手,我对某种异常方法的实现有疑问。这是代码(缩写): class OurException(Exception): """User defined Exception"
我已经创建了以下模式来表示用户和一组线程之间的关联,这些线程按他们的最后一条消息排序(用户已经阅读了哪些线程,哪些没有): CREATE TABLE table(user_id bigint, mes
我正在使用 Python 编写一个简单的自动化脚本,它可能会在多个位置引发异常。在他们每个人中,我都想记录一条特定的消息并退出程序。为此,我在捕获异常并处理它(执行特定的日志记录操作等)后引发 Sys
谁能解释一下为什么这会导致错误: let xs = [| "Mary"; "Mungo"; "Midge" |] Array.iter printfn xs 虽然不是这样: Array.iter pr
在我使用 Play! 的网站上,我有一个管理部分。所有 Admin Controller 都有一个 @With 和一个 @Check 注释。 断开连接后,一切正常。连接后,每次加载页面(任何页面,无论
我尝试连接到 azure 表存储并添加一个对象。它在本地主机上工作得很好,但是在我使用的服务器上我得到以下异常及其内部异常: Exception of type 'Microsoft.Wind
我是一名优秀的程序员,十分优秀!