2011-07-25 30 views
4

我一直在用Python編程一段時間,但我的努力主要是創​​建小型實用程序腳本。我認爲Python是一門很棒的語言,因爲它很有趣,並且可以很容易地編寫乾淨的代碼。確保所有異常都在Python中被捕獲

然而,有一個煩惱我還沒有找到一種治療方法:由於它的動態性,異常可以從各種渠道被拋出,他們會殺了你的計劃,如果他們沒有抓住。對我來說,這是一個「大」程序的痛苦。

在Java(不,我知道Java的比我更瞭解的Python),編譯器實際上是靜態的強制例外的處理,使所有可能的異常引起。是否有可能實現與Python一樣?

+0

有一篇很好的博客文章討論了在python中捕獲異常的不同方法的優缺點:http: //blog.ianbicking.org/good-catch-all-exceptions.html –

+3

即使在Java中,編譯器也不會查找「RuntimeException」及其子類。這是一件好事 - 你不想寫'除了(OutOfMemoryException e){/ *好吧,我們搞砸了* /;提高e;在每一種方法中,你呢? – delnan

+0

相關:[在Python中記錄未捕獲的異常](http://stackoverflow.com/q/6234405/1497596) – DavidRR

回答

3

你能趕上與簡單except:聲明的所有異常。但是這被認爲是危險的,因爲這也包括語法錯誤。

最好的做法是,以涵蓋所有可能的和預期的異常類型的一個except條款。請看下面的例子:

except (IOError, ArgumentError), e: 
    print(e) 

這個例子捕捉兩項預期例外,所有的人都將落空,將被寫入stderr

+0

請注意,在Python 3中它是「as e」,而不是「e」。 – JAB

+4

'except'不捕獲語法錯誤 –

+1

但它確實能夠捕獲像變量/成員名稱拼寫錯誤('NameError','AttributeError')這樣的真正的錯誤,並且(如果吞下異常,OP似乎打算)阻止更高的代碼鏈從實際處理(而不是忽略)錯誤。 – delnan

1

那麼,你可以去捕捉一般的例外,但這不被認爲是好的做法。

try: 
    # Execute code here 
except Exception: 
    # Log error 

更好的方法是捕獲您知道可能發生的特定異常,以便找到處理它們的特定方法。沒有什麼比捕捉你不知道的異常更糟。

+3

這將不會捕獲Python中的'KeyboardInterrupt'> = 2.5 –

+1

就像@Roman Bodnarchuk所說的那樣,'except Exception'不會捕獲一些有用的異常,例如SystemExit,KeyboardInterrupt和GeneratorExit,來捕獲它們,使用pokeball(hem .. ),使用'除了BaseException'。 –

2

所以,其他人已經回答了通常會發現異常的方法。我將採取稍微不同的傾向。我認爲你所問的是如何實現靜態類型語言中出現的同類安全類型。

首先,你可能不想。 python的優勢之一是duck typing。維基百科:

鴨子類型是動態類型的風格,其中對象的當前設置的方法和屬性決定了有效的語義,而不是從一個特定的接口的一個特定的類或實現其繼承

鴨打字的優點是你不必做類型檢查,你可以傳遞任何具有給定方法的對象。

但是,你再有問題:「怎樣才能始終如一地檢查我的代碼是正確的,但不運行它?」當一個錯誤只發生在邊緣情況下時,這特別令人討厭。確保一致的行爲,即使在改變代碼基礎的情況下,一種好方法是編寫unit tests。 Python有許多不同的方法來實現單元測試。最簡單的可能是doctest模塊。但是,如果你想要更強大的功能,還有unittest和單元測試兼容的第三方框架nose

單元測試的好處是,你可以寫他們,當您去,確保尋找甚至罕見的邊緣的情況下,然後運行它們你對程序的顯著變化的任何時間。然後,如果測試失敗,你知道你已經破了一些東西。

+0

雖然我喜歡你的回答,但我更廣泛地解釋了OP的問題。例如,確保你的程序處理'IOError'(如果它適用)與類型安全無關。 – DavidRR

1

你可能想看看sys.excepthook

當異常上升,未捕獲,解釋稱 sys.excepthook有三個參數,異常類,異常 實例,並回溯對象。在交互式會話中,這個 恰好在控制返回提示之前發生;在Python 程序中,這個程序在程序退出之前就發生了。 這種頂級異常的處理可以通過爲sys.excepthook分配另一個 三參數函數來定製。

例子:

def except_hook(type, value, tback): 
    # manage unhandled exception here 
    sys.__excepthook__(type, value, tback) # then call the default handler - if you need to 

sys.excepthook = except_hook 
0
try: 
    # the body of your main loop or whatever 
except Exception: 
    # Import the traceback and system modules 
    import traceback, sys 
    # Prepare the arguments 
    exc_type, exc_value, exc_traceback = sys.exc_info() 
    # Print the exception. There are more args -- read the traceback docs! 
    traceback.print_exception(exc_type, exc_value, exc_traceback) 
    # This is where your house-cleaning code goes. 

我用這個確保事情都在崩潰後留下一個正常的狀態。如果你的「優雅崩潰」代碼依賴於任何拋出異常的情況......請謹慎使用;)