错误和异常(2)

最后更新于:2022-04-01 11:36:00

try...except...是处理异常的基本方式。在原来的基础上,还可有扩展。 ## [](https://github.com/qiwsir/StarterLearningPython/blob/master/217.md#处理多个异常)处理多个异常 处理多个异常,并不是因为同时报出多个异常。程序在运行中,只要遇到一个异常就会有反应,所以,每次捕获到的异常一定是一个。所谓处理多个异常的意思是可以容许捕获不同的异常,有不同的except子句处理。 ~~~ #!/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 ~~~ 将上节的一个程序进行修改,增加了一个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提供了一种方式,将上面代码修改如下: ~~~ 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 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 $ ~~~ > 在python3.x中,常常这样写:`except (ZeroDivisionError, ValueError) as e:` 以上程序中,之处理了两个异常,还可能有更多的异常呢?如果要处理,怎么办?可以这样:`execpt:`或者`except Exception, e`,后面什么参数也不写就好了。 ## [](https://github.com/qiwsir/StarterLearningPython/blob/master/217.md#else子句)else子句 有了`try...except...`,在一般情况下是够用的,但总有不一般的时候出现,所以,就增加了一个else子句。其实,人类的自然语言何尝不是如此呢?总要根据需要添加不少东西。 ~~~ >>> try: ... 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的执行特点,可以写这样一段程序,还是类似于前面的计算,只不过这次要求,如果输入的有误,就不断要求从新输入,知道输入正确,并得到了结果,才不再要求输入内容,程序结束。 在看下面的参考代码之前,读者是否可以先自己写一段呢?并调试一下,看看结果如何。 ~~~ #!/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 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简单说明,这次没有像前面那样写,而是`except Exception, e`,意思是不管什么异常,这里都会捕获,并且传给变量e,然后用`print e`把异常信息打印出来。 ## [](https://github.com/qiwsir/StarterLearningPython/blob/master/217.md#finally)finally finally子句,一听这个名字,就感觉它是做善后工作的。的确如此,如果有了finally,不管前面执行的是try,还是except,它都要执行。因此一种说法是用finally用来在可能的异常后进行清理。比如: ~~~ >>> x = 10 >>> try: ... x = 1/0 ... except Exception, e: ... print e ... finally: ... print "del x" ... del x ... integer division or modulo by zero del x ~~~ 看一看x是否被删除? ~~~ >>> x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'x' is not defined ~~~ 当然,在应用中,可以将上面的各个子句都综合起来使用,写成如下样式: ~~~ try: do something except: do something else: do something finally do something ~~~ ## [](https://github.com/qiwsir/StarterLearningPython/blob/master/217.md#和条件语句相比)和条件语句相比 `try...except...`在某些情况下能够替代`if...else..`的条件语句。这里我无意去比较两者的性能,因为看到有人讨论这个问题。我个人觉得这不是主要的,因为它们之间性能的差异不大。主要是你的选择。一切要根据实际情况而定,不是说用一个就能包打天下。
';