-1

我構建了這兩個代碼,我想知道哪個更好。由於這不是我的程序所關心的,所以我並不一定意味着哪一個更快執行。哪一個更具可讀性?Python:哪個代碼更好?

或者:

A = 1 
B = some_other_value 
try: 
    A /= B 
except ZeroDivisionError: 
    pass 

或者:

A = 1 
B = some_other_value 
if B != 0: 
    A /= B 
+1

**既不是**,因爲這兩個代碼位有效地隱藏了計算出現問題的事實。 –

+1

重複的:http://stackoverflow.com/questions/1835756/using-try-vs-if-in-python – Wessie

+1

python使用異常流控制的事實並不意味着你應該只使用異常流控制。 – mishik

回答

1

當然第二個:

A = 1 
B = some_other_value 
if B != 0: 
    A /= B 

不是因爲它更具可讀性,但因爲你沒有使用一個例外非特殊情況。如果無效輸入或在正常情況下可能導致錯誤的輸入是可能的,那麼您絕不應該使用異常來處理它。

你可以找到(旁邊性能)關於這個網絡上,但在我看來很不錯的解釋總是因爲意圖的:當你處理異常,那麼你明確地告訴讀者,這是一個異常情況,一個錯誤,這在正常的程序流程中不應該發生。在你的情況這不是因爲一個無效的輸入是絕對可能的(每個輸入必須被驗證,總是)

從我的角度來看,你想要處理它的事實意味着這是可能的,然後檢查總是正確的解決方案。就像Ryan所說的,如果你不需要檢查零值,你可能會有更高的多態性,那麼你需要做的是移動支票來處理這種情況(例如在/運算符中,而不是在你使用它的地方)。

編輯
很少有詞彙可以總結我寫的評論。 Python鼓勵一種名爲EAFP的編程風格,當你編寫小腳本時,這是一個很好的資源,但在編寫應用程序和庫時應該謹慎使用它。

它有助於保持碼短(和快速爲最常見的代碼路徑),但它有一個大缺點:如果你不try/execpt包裝每個幾行你會必須處理中間結果和部分計算。一個大的try可能會使應用程序處於不確定狀態(否則它會使您的代碼更不易讀,因爲長列表可能是嵌套的 - try/except/else/finally)。

我同意它有助於使用你的代碼的情況下,你甚至沒有去想但這不靈活,這是脆弱。對於簡短的個人腳本也許可以,但是如果我編寫一個應用程序(或者甚至更多的庫),我想確定我的代碼在哪裏以及如何失敗,我會編寫測試以檢查它如何與不同的輸入一起工作。我不希望它會以我無法預知的方式失敗,意外的輸入>意外的行爲聽起來太像垃圾輸入>垃圾輸出。應用程序必須健壯。在你檢查完你可以檢查的所有東西之後,你甚至必須爲異常情況做好準備(我可以放鬆這個規則,以便檢查可能是偏執的)。

+0

除以零並不例外? –

+0

@HunterMcMillen **不,它不是**,因爲輸入必須總是**驗證**,特別是如果你認爲它可能發生(除了塊以外的空白讓我認爲他們必須是)。 –

+2

@Adriano EAFP更加pythonic,輸入驗證通常是不鼓勵的。而且你需要在此之上進行類型測試來實際驗證輸入,這很少被鼓勵。 –

1

第二個可能更具可讀性,但第一個允許更大的多態性和鴨子打字(在B不是floatint,但是支持除法的對象)的情況下。

大多數討論在這裏似乎是缺少點B可能是支持部門自定義對象。請考慮下面的例子,其中NumType作爲分母。

>>> class NumType(object): # basically, an int wrapper 
...  """Custom number type. Supports division when it is the denominator""" 
...  def __init__(self, val):    
...    self.val = val 
...  def __rdiv__(self, num): 
...    return num/self.val 
... 
>>> c = NumType(1) #normal division works as expected 
>>> 5/c 
5 
>>> c = NumType(7) 
>>> 5./c 
0.7142857142857143 
>>> c = NumType(0) 
>>> 5/c # 0 division causes exception 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 5, in __rdiv__ 
ZeroDivisionError: integer division or modulo by zero 
>>> # pay attention here: 
>>> if c != 0: # condition is True because c is an object, not 0 
...  print 5/c # so this division still occurs, and generates an exception 
... 
Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
    File "<stdin>", line 5, in __rdiv__ 
ZeroDivisionError: integer division or modulo by zero 
>>> # however, this is caught with a try/except 
>>> try: 
...  5/c 
... except ZeroDivisionError: 
...  print '0 division' 
... 
0 division 
0

答案是:取決於。

您是否可以輕鬆編寫適當的測試來處理條件。在這種情況下,你可以。

另一個考慮因素是你的手寫測試是否足夠。在一行代碼中,這很容易。如果你有很多操作,假設一切都很好,並且事後弄清楚,例外情況可能更有意義。 (當然,在這種情況下,輸入驗證通常會更有用)。

與編程中的大多數事情一樣,這是風格和品味的問題。在python中尤其如此,python通常具有多種處理方式(儘管你可能已經閱讀過任何復活節彩蛋),而且它主要基於程序員能夠做出自己的決定的想法(不像Java,確實試圖強制執行一種編程風格,通過使所有事情都比預期的技術更難以且更令人不快)。

想想你在做什麼,爲什麼。儘量不要重複自己。