2013-04-20 111 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只是把意外的異常。