2010-01-21 11 views
11

我在Python except子句中有一些代碼用於執行某些日誌記錄,但日誌記錄代碼本身可能會導致異常。在我的情況下,我想忽略任何可能發生的第二個異常,並引發原始異常。這是非常簡單的例子:處理在except子句中發生的Python異常

try: 
    a = this_variable_doesnt_exist 
except: 
    try: 
     1/0 
    except: 
     pass 
    raise 

運行上面的代碼,我希望能得到:

NameError: name 'this_variable_doesnt_exist' is not defined 

而是在Python 2.x中,我得到:

ZeroDivisionError: integer division or modulo by zero 

我發現在Python 3.x中,它做我想要的。

我無法在Python 2.x文檔中找到關於此的很多評論(除非我錯過了它)。我可以在2.x中實現這個嗎?

回答

15

隨着抽象:

def log_it(): 
    try: 
     1/0 
    except: 
     pass 

try: 
    this = that 
except: 
    log_it() 
    raise 

請問你在Python 2.5

另一種方式來做到這一點是例外存儲在一個變量想要什麼,然後明確地重新提出來:

try: 
    this = that 
except NameError, e: # or NameError as e for Python 2.6 
    try: 
     1/0 
    except: 
     pass 
    raise e 

請注意,您可能不應該僅僅使用一個光禿禿的except來捕捉所有可能出現的情況 - 通常最好捕獲您期望的特定例外情況如果發生嚴重和致命異常(例如內存不足),則會發生。

18

我相信你看到的是exception chaining,這是一個change in Python 3的結果。

從PEP的動機部分:

在一個異常(異常A)的處理,有可能的是,可能會出現另外的異常(異常B)。在今天的Python(版本2.4)中,如果發生這種情況,異常B向外傳播,異常A丟失。爲了調試這個問題,瞭解這兩個例外是很有用的。 __context__屬性自動保留此信息。

然後PEP繼續描述新的異常鏈接(在Py3k中實現),詳細描述爲—這是一個有趣的閱讀。我今天學了些新東西。

+0

如何明確處理次要異常?請在你的回答中加入這個 – 2017-04-03 23:13:41

0

在我的CausedException class中,我關注了Python 2.x(也適用於Python 3,以防您想傳遞原因樹而不是簡單原因鏈)。也許它可以幫助你。

+1

雖然這可能在理論上回答這個問題,[這將是可取的](http://meta.stackexchange.com/q/8259)在這裏包括答案的基本部分,並提供鏈接以供參考。 – 2013-11-10 19:35:15