2013-04-20 75 views
16

如何处理除一个例外以外的所有情况?处理除一个例外以外的所有情况

try: 
    something 
except NoChildException: 
    raise NoChildException 
except: 
    pass 
+4

简单的回答:不要。捕捉所有异常是非常糟糕的做法,因为你会倾向于捕捉你不想要的东西,从而掩盖错误。做这样的事情只有少数合法案件。 – 2013-04-20 18:10:03

+2

你似乎已经回答了你自己的问题。告诉我们为什么你对你有什么不满意。 – 2013-04-20 18:15:40

+0

@Robᵩ不太可能,他的例子会形成一个*新的*异常,而不是重新提升旧的。 – 2013-04-20 18:18:11

回答

24

答案是简单地做raise

try: 
    ... 
except SomeException: 
    raise 
except: 
    ... 

raise没有任何表情后,它会简单提出最后抛出的异常(即使它被处理!)。这大致相当于:

except SomeException as e: 
    raise e 

如果您认为例外可能在catch块(在这种情况下,显然是不可能的)被抛出,你应该使用后者的格式,以确保您重新引发右例外。

然而,正如我的评论指出:

简单的回答:不。捕捉所有的例外情况是非常糟糕的做法,因为你会倾向于去捕捉那些你并不想要的, 掩盖错误。 做这样的事情只有很少的合法情况。

只是发现你认为你的代码可能抛出的错误,并且你知道如何处理,并留下任何其他东西。如果发生任何其他事情,您的程序将退出 - 这是你想,因为你可以看到它为什么发生并正确处理它。

+2

+1“不要做” – Aya 2013-04-20 18:19:18

+0

我同意。但我得到这个: 失败:您的Patient.update方法捕获一个类型为ZeroDivisionError的异常,当它不应该有。 你不应该在代码中使用裸'except'子句。只捕获NoChildExceptions。 而不是这样的: 成功忽略类型引发的异常:ZeroDivisionError 成功忽略类型引发的异常:NameError 成功忽略类型引发的异常:AttributeError的 成功忽略类型引发的异常:类型错误 成功忽略类型引发的异常:ValueError 成功捕获NoChildException 测试完成 – 2013-04-20 19:38:57

+0

@IvanVulović所以你想要的只是* catch * NoChildException(这与你所要求的完全相反),所以只需要'try:... except NoChildException:...',不需要任何幻想。 – 2013-04-20 20:13:56

2

我会提供这个作为接受答案的改进。

try: 
    dosomestuff() 
except MySpecialException: 
    ttype, value, traceback = sys.exc_info() 
    raise ttype, value, traceback 
except Exception as e: 
    mse = convert_to_myspecialexception_with_local_context(e, context) 
    raise mse 

这种方法通过维持原来的堆栈跟踪时MySpecialException被抓住了,所以当你的顶层异常处理记录异常,你会得到一个指向到原始异常被抛出回溯上公认的答案改善。

0

我发现了一个捕获所有错误的上下文,但一个并不是一件坏事,即单元测试。

如果我有一个方法:

def my_method(): 
    try: 
     something() 
    except IOError, e: 
     handle_it() 

那么它可以振振有词有一个单元测试,看起来像:

def test_my_method(): 
    try: 
     my_module.my_method() 
    except IOError, e: 
     print "shouldn't see this error message" 
     assert False 
    except Exception, e: 
     print "some other error message" 
     assert False 
    assert True 

因为你现在已经检测到my_method只是把意外的异常。