异常处理
到目前为止,在Python程序中遇到错误,或"异常",以为着整个程序崩溃。你不希望这发生在真实世界的程序中,相反,你希望程序能检测错误,处理它们,然后继续运行。
例如,考虑以下程序,它有一个"除数为零"的错误。输入代码如下:
def spam(divideby):
return 42 / divideby
print(spam(2))
print(spam(12))
print(spam(0))
print(spam(1))
输出结果:
21.0
3.5
Traceback (most recent call last):
File "/Users/limingda/Desktop/\u684c\u9762\u6587\u4ef6/python/python1/test.py", line 6, in <module>
print(spam(0))
File "/Users/limingda/Desktop/\u684c\u9762\u6587\u4ef6/python/python1/test.py", line 2, in spam
return 42 / divideby
ZeroDivisionError: division by zero
我们已经定义了名为spam的函数,给了它一个变元,然后打印出该函数带各种参数的值。当试图用一个数除以零时,就会发生ZeroDivisionError。根据错误信息中给出的航航,我们知道spam()中的return语句导致了一个错误。
函数作为"黑盒",通常,对于一个函数,你要知道的就是它的输入值(变元)和输出值。你并非总是需要加重自己的负担,弄清楚函数的代码实际是怎样工作的。如果以这种高层的方式来思考函数,通常大家会说,你将该函数看成是一个黑盒。
这个思想是现代编程的基础。本章节后面将向你展示一些模块,其中的函数是由其他人编写的。尽管你在浩气的时候也可以看一看源代码,但为了能使用它们,你并不需要知道它们是如何工作的。而且,因为鼓励在编写函数时不使用全局变量,你通常也不必担心函数的代码会与程序的其他部分发生交叉影响。
错误可以有try和except语句来处理。那些可能出错的语句被放在try子句中。如果错误发生,程序执行就转到接下来的except子句开始处。
可以将前面除数为零的代码放在一个try子句中,让except子句包含代码,来处理该错误发生时应该做的事。
def spam(divideby):
try:
return 42 / divideby
except ZeroDivisionError:
print('Error:Invalid argument.')
print(spam(2))
print(spam(12))
print(spam(0))
print(spam(1))
如果在try子句中的代码导致一个错误,程序执行就立即转到except子句的代码。在运行哪些代码之后,执行照常继续。运行上面的代码输出如下:
21.0
3.5
Error:Invalid argument.
None
42.0
请注意,在函数调用的try语句块中,发生的所有错误都会被捕捉。请考虑以下程序,它的做法不一样,将spam()调用放在语句块中:
def spam(divideby):
return 42 / divideby
try:
print(spam(2))
print(spam(12))
print(spam(0))
print(spam(1))
except ZeroDivisionError:
print('Error:Invalid argument.')
输出结果:
21.0
3.5
Error:Invalid argument.
print(spam(1))从未被执行是因为,一旦执行到except子句的代码,就不会回到try子句。它会继续照常向下执行。