跳转到内容

非程序员的 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 部分),使其在用户在菜单中没有输入任何数据时不会崩溃。

华夏公益教科书