2016-02-29 106 views
3

如果我在寫某些代碼的時候不確定某事,我試着再次閱讀The Zen of Python。這段時間,這些線條猶豫着我。處理異常的最佳方法是什麼?

Errors should never pass silently. 
Unless explicitly silenced. 

在當前代碼我有一些功能,這可能是這樣的:

def add_v_1(a, b): 
    return a + b 

,併爲它們呼叫喜歡:

c = add_v_1(7, []) 

異常這樣的代碼將泡漲,抓住在上層。

但是它應該是這樣嗎?

add_v_1可以引發TypeError異常,我想從中恢復。 所以,函數的調用可能會是:

try: 
    c = add_v_1(7, []) 
except TypeError: 
    print "Incorrect types!" 

但對於每一個電話,我應該做的異常處理。看起來很沉重。

所以,我可以這樣做:

def add_v_2(a, b): 
    try: 
     return a + b 
    except TypeError: 
     print "Incorrect types!" 

和電話是:

c = add_v_2(7, []) 

看起來更乾淨。

似乎所有這些方法都遵循The Zen of Python,但哪一個更好?

+1

我會說這取決於你的情況,如果你處理你仍然必須處理函數內部的異常它也在外面,因爲它會返回None。 – Hacketo

+0

@Hacketo你會用當前的例子做什麼? –

回答

3

參照你的例子,這是值得商榷的,你是否應該抓住裏面的功能異常。這樣做會從函數返回None,然後通過檢查函數的返回值來加載調用代碼,並將None視爲錯誤。它有效地用錯誤檢查取代異常處理。前者通常更加Pythonic。

你應該問一下,如果試圖添加兩個完全不同的數據類型是否有意義。在這種情況下這樣做似乎是一個編程錯誤,而不是正常執行期間所期望的那種事情。

你能做些什麼來處理這樣的錯誤?除了None之外,似乎沒有任何有用的值可以在函數的預期輸出域內返回,以表示無法產生結果。但調用代碼仍然必須執行某種錯誤檢查...所以它可能只是處理一個異常 - 至少它只需要處理一次。

但是這個例子很有意思,很難給出一攬子建議。在這種特殊情況下,出於上述原因,我會允許異常傳播到調用代碼並在那裏處理。

0

輸入:

def add_v_2(a, b): 
    try: 
     return a + b 
    except Exception as e: 
     print str(e) 
c = add_v_2(7, []) 
print (c) 

輸出:

unsupported operand type(s) for +: 'int' and 'list' 
None 
+0

@viakondratiuk - 在你的代碼中,第二個是最好的,如果有的話你會再次做同樣的事情,不需要再次使用try catch – GThamizh

+2

我不能推薦捕捉'Exception',這遠非一般。您應該捕獲您期望並可以處理的異常,在這種情況下,您可以捕獲「TypeError」。 – mhawke

2

你應該處理除非你能夠從中恢復。如果您嘗試添加兩個不兼容類型的值,則無法從中恢復(沒有更多上下文)。

讓我們假設你寫了一個IntegerWrapper類,你的函數「add_v_2」通常應該試圖連接兩個值。

def add_v_2(a, b): 
    try: 
     return a + b 
    except TypeError as e: 
     if isinstance(a, IntegerWrapper): 
      return str(a) + b 
     else: 
      print("I dont know how to handle this type: " + type(a).__name__) 
      # reraise the error so the caller can handle it 
      raise 

這將嘗試從a存在「錯誤類型」中恢復,但如果你知道如何從中恢復。如果它不知道(a是另一種類型),它會重新評估異常,以便知道如何處理這個問題的人會看到錯誤。

(當然是實現包含錯誤,它並不意味着是一個「良好的執行」)

相關問題