2010-01-27 73 views
8

引發異常和簡單打印錯誤有什麼區別。引發異常與打印?

例如,什麼使用以下的好處:

if size < 0: 
     raise ValueError('number must be non-negative') 

簡單地代替:

if size < 0: 
     print 'number must be non-negative' 

我是一個新手,請把我很容易。 :)

+3

當您嘗試此代碼時,您觀察到了什麼差異? – 2010-01-27 12:27:47

回答

8

Raising an error在該點停止整個程序(除非異常被捕獲),而printing消息只是寫東西stdout - 輸出可能被管道輸送到另一個工具,或者有人可能無法運行從應用程序命令行,並且print輸出可能永遠不會被看到。

例如,如果你的代碼是什麼樣子:

if size < 0: 
    print 'size must be non-negative' 
else: 
    print size * 4 

,我打電話給你的腳本,如:

yours.py number_source.txt | sum_all_lines.sh

如果yours.py輸出數字之間的純文本,那麼也許我的sum_all_lines.sh將失敗,因爲它期待所有數字。但是,如果yours.py由於例外而退出,那麼sum_all_lines.sh不會完成,並且我將清楚爲什麼該總和失敗。

當然,這只是一個例子,您的具體情況可能會完全不同。

+2

您省略了這個:http: //docs.python.org/reference/simple_stmts.html#the-raise-statement和http://docs.python.org/reference/simple_stmts.html#the-print-statement。 – 2010-01-27 12:27:22

6

這取決於您是否可以在檢測到size < 0的位置處理size < 0

如果您可以通過印刷直線距離,然後print處理它,否則,引發異常,委託該條件的處理的東西進一步向上調用堆棧,像這樣:

def divide_three_by(val): 
    if val == 0: 
    raise ValueError("Can't divide by 0") 
    return 3/val 

try: 
    divide_three_by(some_value_from_user) 
except ValueError: 
    print "You gave stupid input" 

在(上面的例子中,divide_three_by函數不知道如果你傳入0時該怎麼做 - 有時候你可能只是想打印一條消息(例如,如果val來自用戶輸入),有時候你可能只想忽略它,並分配一個默認值。由於函數不知道該怎麼做,它應該將處理這個條件的責任傳遞給調用堆棧的任何東西(如果它不能在那裏處理,它將繼續傳遞給堆棧,直到處理它,或者直到它到達頂層,此時程序將終止)。

有關在Python中處理異常的更多信息,請參閱Python文檔中的Errors and Exceptions tutorial

+0

我應該指出,我的例子*非常人爲*,因爲存在'ZeroDivisionError'(http://docs.python.org/library/exceptions.html#exceptions.ZeroDivisionError) – 2010-01-27 12:38:52

2

關鍵的區別在於程序是否會在錯誤檢查後繼續運行。

對於這種情況:

if size < 0: 
    print 'number must be non-negative' 

這將只打印信息到標準輸出,並計劃將繼續以往的檢查。因此,如果在某一點在後面的代碼你使用size,它是小於0你可能會得到一個錯誤。

對於其他情況:

if size < 0: 
    raise ValueError('number must be non-negative' 

在這種情況下,程序將不會繼續過去的檢查中,將引發異常。如果不處理,則整個程序將終止。

大多數時候,你會想拋出異常,並有捕捉異常,並講述了錯誤的使用外異常處理程序的時間,如果可能的話讓他們重新進入輸入法。

3

另一個考慮因素是開發在其他程序中可能使用的模塊時。在這種情況下,最好拋出異常並讓調用代碼處理錯誤。來電者應該知道出現了問題,並據此採取行動。

... richie