X Tutup
>你们得救是本乎恩,也因着信。这并不是出于自己,乃是神所赐的;也不是出于行为,免得有人自夸。(EPHESIANS 2:8-9) #错误和异常(2) ###处理多个异常 `try...except...`是处理异常的基本方式。在此基础上,还可有扩展,能够处理多个异常。 处理多个异常,并不是因为同时报出多个异常。程序在运行中,只要遇到一个异常就会有反应,所以,每次捕获到的异常一定是一个。所谓处理多个异常的意思是可以容许捕获不同的异常,由不同的`except`子句处理。 Python 2: #!/usr/bin/env python # coding=utf-8 while 1: print "this is a division program." c = raw_input("input 'c' continue, otherwise logout:") if c == 'c': a = raw_input("first number:") b = raw_input("second number:") try: print float(a)/float(b) print "*************************" except ZeroDivisionError: print "The second number can't be zero!" print "*************************" except ValueError: print "please input number." print "************************" else: break Python 3: #!/usr/bin/env python # coding=utf-8 while 1: print("this is a division program.") c = input("input 'c' continue, otherwise logout:") if c == 'c': a = input("first number:") b = input("second number:") try: print(float(a)/float(b)) print("*************************") except ZeroDivisionError: print("The second number can't be zero!") print("*************************") except ValueError: print("please input number.") print("************************") else: break 将上节的一个程序进行修改,增加了一个except子句,目的是如果用户输入的不是数字时,捕获并处理这个异常。测试如下: $ python 21701.py this is a division program. input 'c' continue, otherwise logout:c first number:3 second number:"hello" #输入了一个不是数字的东西 please input number. #对照上面的程序,捕获并处理了这个异常 ************************ this is a division program. input 'c' continue, otherwise logout:c first number:4 second number:0 The second number can't be zero! ************************* this is a division program. input 'c' continue, otherwise logout:4 如果有多个`except`,try里面遇到一个异常,就转到相应的`except`子句,其它的忽略。如果`except`没有相应的异常,该异常也会抛出,不过这是程序就要中止了,因为异常“浮出”程序顶部。 除了用多个`except`之外,还可以在一个`except`后面放多个异常参数,比如上面的程序,可以将`except`部分修改为: except (ZeroDivisionError, ValueError): print "please input rightly." print "********************" 运行的结果就是: $ python 21701.py this is a division program. input 'c' continue, otherwise logout:c first number:2 second number:0 #捕获异常 please input rightly. ******************** this is a division program. input 'c' continue, otherwise logout:c first number:3 second number:a #异常 please input rightly. ******************** this is a division program. input 'c' continue, otherwise logout:d $ 需要注意的是,`except`后面如果是多个参数,一定要用圆括号包裹起来。否则,后果自负。 在对异常的处理中,前面都是自己写一个提示语,发现自己写的不如内置的异常错误提示好。希望把它打印出来。但是程序还能不能中断,怎么办? Python提供了一种方式,将上面代码修改如下: Python 2: while 1: print "this is a division program." c = raw_input("input 'c' continue, otherwise logout:") if c == 'c': a = raw_input("first number:") b = raw_input("second number:") try: print float(a)/float(b) print "*************************" except (ZeroDivisionError, ValueError), e: print e print "********************" else: break Python 3: while 1: print("this is a division program.") c = input("input 'c' continue, otherwise logout:") if c == 'c': a = input("first number:") b = input("second number:") try: print(float(a)/float(b)) print("*************************") except (ZeroDivisionError, ValueError) as e: print(e) print("********************") else: break 运行一下,看看提示信息。 $ python 21702.py this is a division program. input 'c' continue, otherwise logout:c first number:2 second number:a #异常 could not convert string to float: a ******************** this is a division program. input 'c' continue, otherwise logout:c first number:2 second number:0 #异常 float division by zero ******************** this is a division program. input 'c' continue, otherwise logout:d $ 注意Python 3中的写法`except (ZeroDivisionError, ValueError) as e:` 在上面程序中,只处理了两个异常,还可能有更多的异常,如果要处理,怎么办?可以这样:`execpt:`或者`except Exception, e`、`except Exception as e`,后面什么参数也不写就好了。 ###else子句 有了`try...except...`,在一般情况下是够用的,但总有不一般的时候出现,所以,就增加了一个`else`子句。其实,人类的自然语言何尝不是如此呢?总要根据需要添加不少东西。 >>> try: ... print "I am try" #Python 3: print("I am try"),下同,从略 ... except: ... print "I am except" ... else: ... print "I am else" ... I am try I am else 这段演示,能够帮助读者理解else的执行特点。如果执行了`try`,则`except`被忽略,但是else被执行。 >>> try: ... print 1/0 ... except: ... print "I am except" ... else: ... print "I am else" ... I am except 这时候else就不被执行了。 理解了else的执行特点,可以写这样一段程序,还是类似于前面的计算,只是如果输入的有误,就不断要求从新输入,直到输入正确并得到了结果,才不再要求输入内容,然后程序结束。 在看下面的参考代码之前,读者是否可以先自己写一段并调试?看看结果如何。 Python 2: #!/usr/bin/env python # coding=utf-8 while 1: try: x = raw_input("the first number:") y = raw_input("the second number:") r = float(x)/float(y) print r except Exception, e: print e print "try again." else: break Python 3: #!/usr/bin/env python # coding=utf-8 while 1: try: x = input("the first number:") y = input("the second number:") r = float(x)/float(y) print(r) except Exception as e: print(e) print("try again.") else: break 先看运行结果: $ python 21703.py the first number:2 the second number:0 #异常,执行except float division by zero try again. #循环 the first number:2 the second number:a #异常 could not convert string to float: a try again. the first number:4 the second number:2 #正常,执行try 2.0 #然后else:break,退出程序 相当满意的执行结果。 程序中的`except Exception, e`或`except Exception as e:`的含义是不管什么异常,这里都会捕获,并且传给变量`e`,然后用`print e`或者`print(e)`把异常信息打印出来。 ###finally `finally`子句,一听这个名字,就感觉它是做善后工作的。的确如此,如果有了`finally`,不管前面执行的是`try`,还是`except`,最终都要执行它。因此一种说法是将`finally`用在可能的异常后进行清理。比如: >>> x = 10 >>> try: ... x = 1/0 ... except Exception, e: #Python 3: except Exception as e: ... print e #Python 3: print(e) ... finally: ... print "del x" #Python 3: print(e) ... del x ... integer division or modulo by zero del x 看一看`x`是否被删除? >>> x Traceback (most recent call last): File "", line 1, in NameError: name 'x' is not defined 当然,在应用中可以将上面的各个子句都综合起来使用,写成如下样式: try: do something except: do something else: do something finally do something ------ [总目录](./index.md)   |   [上节:错误和异常(1)](./216.md)   |   [下节:错误和异常(3)](./218.md) 如果你认为有必要打赏我,请通过支付宝:**qiwsir@126.com**,不胜感激。
X Tutup