跳轉到內容

非程式設計師的 Python 2.6 教程/處理不完美

來自 Wikibooks,開放世界開放書籍

...或如何處理錯誤

[編輯 | 編輯原始碼]

因此,你現在有了完美的程式,它執行得完美無瑕,除了一個細節,它會在無效的使用者輸入時崩潰。不必害怕,因為 Python 有一個特殊的控制結構供你使用。它叫做 try,它試圖做某事。這是一個有問題的程式的例子

print "Type Control C or -1 to exit"
number = 1
while number != -1:
    number = int(raw_input("Enter a number: "))
    print "You entered:", number

注意當你輸入 @#& 時,它會輸出類似的東西

Traceback (innermost last):
 File "try_less.py", line 4, in ?
    number = int(raw_input("Enter a number: "))</syntaxhighlight>

ValueError: invalid literal for int(): @#&

正如你所看到的,int() 函式對數字 @#& 不滿意(它應該不滿意)。最後一行顯示了問題所在;Python 發現了一個 ValueError。我們的程式如何處理這個問題?我們首先要做的是:將發生錯誤的地方放在一個 try 塊中,其次是:告訴 Python 我們希望如何處理 ValueError。以下程式就是這樣做的

print "Type Control C or -1 to exit"
number = 1
while number != -1:
    try:
        number = int(raw_input("Enter a number: "))
        print "You entered:", number
    except ValueError:
        print "That was not a number."

現在,當我們執行新程式並輸入 @#& 時,它會告訴我們“那不是一個數字”,並繼續執行它之前正在做的事情。

當你的程式一直出現一些你知道如何處理的錯誤時,將程式碼放在一個 try 塊中,並將處理錯誤的方式放在 except 塊中。

這是一個更復雜的錯誤處理示例。

# Program by Mitchell Aikens 2012
# No copyright.
import math

def main():
	success = 0
	while (success == 0):
		try:
			epact()
			success = 1
		except ValueError:
			print "Error. Please enter an integer value."
			year = 0
		except NameError:
			print "Error. Please enter an integer value."
			year = 0
		except SyntaxError:
			print "Error. Please enter an integer value."
			year = 0
		finally:
			print "Program Complete"

def epact():
    
    year = int(input("What year is it?\n"))
    C = year/100
    epactval = (8 + (C/4) - C + ((8*C + 13)/25) + 11 * (year%19))%30
    print "The Epact is: ",epactval

main()

上面的程式使用了前面幾課的知識以及本課的知識。讓我們分段看看上面的程式。

在定義名為“main”的函式後,我們告訴它我們想“嘗試”名為“epact”的函式。它在沒有“success”的情況下“while”執行。然後,直譯器轉到 year = int(input("What year is it?\n")) 行。直譯器獲取使用者輸入的值並將其儲存在名為“year”的變數中。

如果輸入的值不是整數或浮點數(它將被直譯器轉換為整數),則會引發異常,並且 try 塊的執行將在 success 被分配值為 1 之前結束。

讓我們看看一些可能的異常。上面的程式沒有為每種可能的異常提供 except 子句,因為有許多型別的異常。

如果輸入的年份值為字母字元,則會引發 NameError 異常。在上面的程式中,這被 except NameError: 行捕獲,並且直譯器執行 except NameError: 下面的列印語句,然後將“year”的值設定為 0 作為預防措施,清除任何非數字。然後,直譯器跳回到 while 迴圈的第一行,並且該過程重新開始。

上面的過程對我們擁有的其他異常也是相同的。如果引發了異常,並且我們的程式中有一個與其匹配的 except 子句,則直譯器將跳到適當的 except 子句下的語句,並執行它們。

finally 語句有時也用於異常處理。把它想象成王牌。finally 子句下的語句將無論我們是否引發異常都會被執行。finally 語句將在任何位於其之前的 tryexcept 子句之後被執行。

下面是一個更簡單的示例,我們沒有迴圈,並且 finally 子句無論是否發生異常都會被執行。

#Program By Mitchell Aikens 2012
#Not copyright.

def main():
    try:
        number = int(input("Please enter a number.\n"))
        half = number/2
        print "Half of the number you entered is ",half
    except NameError:
        print "Error."
    except ValueError:
        print "Error."
    except SyntaxError:
        print "Error."
    finally:
        print "I am executing the finally clause."
        
main()

如果我們要為 number = int(input("Please enter a number.\n")) 輸入字母值,輸出將如下所示

Please enter a number.
t
Error.
I am executing the finally clause.

至少更新電話號碼程式(在 檔案 I/O 部分),使其在使用者在選單中沒有輸入任何資料時不會崩潰。

華夏公益教科書