python基础-异常(exception)处理
作者:程小航
版权声明:原创作品,谢绝转载!否则将追究法律责任。
程序中难免出现错误,而错误分成两种,即语法错误和逻辑错误。语法错误根本过不了python解释器的语法检测,必须在程序执行前就改正,还有一种就是逻辑错误,对逻辑错误的处理是本篇博客介绍的重点。
一.什么是异常
1>.python解释器检测到错误,触发异常(也允许程序员自己触发异常);
2>.程序员编写特定的代码,专门用来捕捉这个异常(这段代码与程序逻辑无关,与异常处理有关);
3>.如果捕捉成功则进入另外一个处理分支,执行你为其定制的逻辑,使程序不会崩溃,这就是异常处理;
二.为什么要处理异常
python解析器去执行程序,检测到了一个错误时,触发异常,异常触发后且没被处理的情况下,程序就在当前异常处终止,后面的代码不会运行,谁会去用一个运行着突然就崩溃的软件。所以你必须提供一种异常处理机制来增强你程序的健壮性与容错性 .
三.如何进行异常处理
首先须知,异常是由程序的错误引起的,语法上的错误跟异常处理无关,必须在程序运行前就修正.
1>.常见的异常
1 #以下是常见的逻辑异常,注意,语法错误不算是逻辑异常哟! 2 #1>. NameError,即变量错误,没有定义就被调用了,案例展示如下: 3 # a 4 #2>. TypeError,即类型错误,传入的数据类型应该是一个迭代器,案例展示如下: 5 # sum(1,2,3) 6 #3>.KeyError,上面定义的字典是空的,但是你还得去取值,当然啥也取不出来啦!不得不抛出异常,案例展示如下: 7 # dic = {} 8 # dic["key"] 9 #4>.IndexError,索引错误,在列表中不存在对应的下标就会爆出异常,案例展示如下: 10 # array = [] 11 # array[1] 12 #5>.StopIteration,迭代器的对象遍历完毕之后会跑出的异常,案例展示如下: 13 # array = [1,2] 14 # array_iterator = iter(array) 15 # next(array_iterator) 16 # next(array_iterator) 17 # next(array_iterator) 18 #6>.ValueError:,即传值错误,要求你传入数字,结果你传入的是字母,案例展示如下: 19 # number = input("num:") 20 # int(number)
2>.单分支异常处理
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :rianley 4 #blog:http://www.cnblogs.com/rianley 5 #EMAIL:rianley@qq.com 6 7 try: 8 number = input("Your number:>>>").strip() 9 number = int(number) 10 print("您输入的数字是:%d" % number) 11 except ValueError: 12 print("请输入一个整数!") 13 ''' 14 放在try中的代码如果遇到except中的错误类型,就会执行except的代码且一旦发生异常,try中的代码会停止在异常处, 15 但不影响try语句之外的代码执行。一种错误类型只能处理对应的一种错误,其它错误还照样报错。 16 '''
3>.多分支异常处理
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :rianley 4 #blog:http://www.cnblogs.com/rianley 5 #EMAIL:rianley@qq.com 6 7 try: 8 number = input("Your number:>>>").strip() 9 number = int(number) 10 print("您输入的数字是:%d" % number) 11 a 12 sum(1,2,3) 13 except ValueError: 14 print("请输入一个整数!") 15 except NameError as name_error: 16 print("产生了一个%s"%name_error) 17 except TypeError: 18 print("咋又诞生了一个错误呢!")
4>.万能异常处理
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :rianley 4 #blog:http://www.cnblogs.com/rianley 5 #EMAIL:rianley@qq.com 6 7 try: 8 number = input("Your number:>>>").strip() 9 number = int(number) 10 print("您输入的数字是:%d" % number) 11 a 12 sum(1,2,3) 13 except Exception as err: 14 print("你的程序异常啦!%s"%err) 15 16 """ 17 对于你已经可以遇见的但是不能完全规避的必须要处理的异常,你应该去制定他的处理方式,对于其它你不能预料的,在使用万能异常处理。 18 """
5>.异常处理的else语句
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :rianley 4 #blog:http://www.cnblogs.com/rianley 5 #EMAIL:rianley@qq.com 6 7 try: 8 a = 1 9 except NameError as err: 10 print(err) 11 else: 12 print("当try语句中不会发生异常的时候执行else中的代码啦!")
6>.异常处理之finally语句
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :rianley 4 #blog:http://www.cnblogs.com/rianley 5 #EMAIL:rianley@qq.com 6 7 8 def func(): 9 try: 10 f = open('rianley.php') 11 int(f.read()) 12 print("*********开始关闭文件啦!") #代码并不会被执行 13 f.close() 14 print("文件已经被关闭啦**********") 15 except ValueError as err: 16 return -1 17 else: 18 print("以上代码没有异常") #try代码块中没有异常的时候才会被执行,finally代码块中代码永远执行。 19 finally: 20 print("开始关闭文件啦!") 21 f.close() 22 print("文件已经被关闭啦") 23 24 ''' 25 finally关键字: 26 不管程序遇到何种的异常,或是中途return啦,最终finally的代码都会被执行哟!一般用于清理工作,即把之前打开的链接, 27 文件等资源都关掉,避免因为程序异常造成的浪费资源和逻辑问题。 28 ''' 29 30 print(func())
7>.主动触发异常
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :rianley 4 #blog:http://www.cnblogs.com/rianley 5 #EMAIL:rianley@qq.com 6 7 try: 8 raise ValueError #主动触发异常! 9 except ValueError: 10 print("Error")
8>.断言
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :rianley 4 #blog:http://www.cnblogs.com/rianley 5 #EMAIL:rianley@qq.com 6 7 8 9 assert 1 == 1 10 11 print("正确执行") 12 13 assert 1 == 2 #一言不合就报错!只要这个条件不满足就抛出异常!断言一般用于在一个功能的最开始 14 15 print("错误执行")
四.什么时候用异常处理
其实异常处理我是不建议大家用它的,try....except语句应该尽量少用,因为他本身就是你附加给程序的一个异常处理的逻辑,与你的主要的工作是没有关系的,这种东西加的多了,会导致你的代码可读性变差,只有在有些异常无法预知的情况下,才应该加上try...except,其它的逻辑错误应该尽量修正。
五.自定义异常处理
# 定义了一个自己的异常类,可在适当时候通过raise来触发它 class ExError(Exception): pass def exrror(num): if num ==100: raise ExError("the num must not be %d" %num) else: print(num) exrror(100) “““ --------------------------------------------------------------------------- ExError Traceback (most recent call last) <ipython-input-28-febd2db30885> in <module>() print(num) ---> 11 exrror(100) <ipython-input-28-febd2db30885> in exrror(num) def exrror(num): if num ==100: ----> 7 raise ExError("the num must not be %d" %num) else: print(num) ExError: the num must not be 100 ”””
六.异常处理 练习demo(python代码)
1 ''' 2 1 什么是异常处理 3 异常是程序发生错误的信号,即程序一旦出错就会立刻产生一个异常,如果该异常没有被处理 4 那么异常就抛出来,程序的运行也随之终止 5 6 异常分为三部分: 7 异常的类型 8 异常的内容、提示信息 9 异常的追踪/定位信息信息 10 11 12 捕捉/检测异常,一旦发生异常就立刻执行相应的处理逻辑,而不是任由异常抛出来终止程序 13 2 为何要进行异常处理 14 增强程序的健壮性 15 16 3 如何进行异常处理 17 18 try...except... 19 ''' 20 # 异常又分为两大类: 21 #1、语法上错误导致的异常 #SyntaxError 22 # 针对语法上的错误,应该在程序运行前就立刻改正 23 # if 1 > 2 # 24 # print('====') 25 # 26 # print( 27 28 29 #2、逻辑错误导致的异常 30 # int('xxxxxxx') #ValueError 31 32 # age #NameError 33 34 # for i in 10: #TypeError: 35 # pass 36 37 # l=[] 38 # l[1111111] #IndexError 39 40 # d={'x':1} 41 # d['y'] #KeyError 42 43 # 1 / 0 #ZeroDivisionError 44 45 #针对逻辑上的异常才应该使用try...except去捕捉异常进行处理 46 #1、异常的单分支 47 # try: 48 # age=10 49 # age 50 # l=[1,2,3] 51 # l[100] 52 # d={'x':1} 53 # d['y'] 54 # print('====>') 55 # except IndexError: 56 # print('=====>NameError') 57 # 58 # 59 # print('其他代码') 60 61 62 63 #2、异常的多分支 64 # try: 65 # age 66 # l=[1,2,3] 67 # # l[100] 68 # d={'x':1} 69 # # d['y'] 70 # print('====>') 71 # except NameError as e: 72 # print('NameError: %s' %e) 73 # except IndexError as e: 74 # print('IndexError: %s' %e) 75 # except KeyError as e: 76 # print('KeyError: %s' %e) 77 # 78 # print('其他代码') 79 80 81 82 83 #3、万能异常:Exception,可以匹配所有种类的异常 84 # try: 85 # # age 86 # l=[1,2,3] 87 # # l[100] 88 # d={'x':1} 89 # d['y'] 90 # print('====>') 91 # except Exception as e: 92 # print(e) 93 # 94 # 95 # print('其他代码') 96 97 98 99 #4、多分支+Exception,注意Exception一定要放到except 其他异常的的后面 100 # try: 101 # # age 102 # l=[1,2,3] 103 # l[100] 104 # d={'x':1} 105 # d['y'] 106 # print('====>') 107 # except IndexError as e: 108 # print('IndexError: %s' %e) 109 # except KeyError as e: 110 # print('KeyError:%s' %e) 111 # except Exception as e: 112 # print(e) 113 # 114 # print('其他代码') 115 116 117 #5、try...else,else会在被检测的代码块没有异常发生的情况下执行, else一定要与except连用,并且一定要放到多个except后面 118 # try: 119 # # age 120 # l=[1,2,3] 121 # # l[100] 122 # d={'x':1} 123 # # d['y'] 124 # print('====>') 125 # except IndexError as e: 126 # print('IndexError: %s' %e) 127 # except KeyError as e: 128 # print('KeyError:%s' %e) 129 # except Exception as e: 130 # print(e) 131 # else: 132 # print('else的代码只有在被检测的代码块没有异常发生的情况下才会执行') 133 # 134 # 135 # print('其他代码') 136 137 138 #6、try...finally,finnaly的代码会什么时候运行? finally应放到最后面 139 # try: 140 # # age 141 # f=open('a.txt','w') 142 # l=[1,2,3] 143 # l[100] 144 # d={'x':1} 145 # # d['y'] 146 # print('====>') 147 # except IndexError as e: 148 # print('IndexError: %s' %e) 149 # except KeyError as e: 150 # print('KeyError:%s' %e) 151 # except Exception as e: 152 # print(e) 153 # else: 154 # print('else的代码只有在被检测的代码块没有异常发生的情况下才会执行') 155 # finally: 156 # print('finally的代码,无论被检测的代码有无异常,都会执行,通常在finally内做一些回收资源的事情') 157 # f.close() 158 # 159 # print('其他代码') 160 161 162 # try: 163 # # age 164 # l=[1,2,3] 165 # # l[100] 166 # d={'x':1} 167 # # d['y'] 168 # print('====>') 169 # except Exception: 170 # pass 171 # else: 172 # print('else的代码只有在被检测的代码块没有异常发生的情况下才会执行') 173 # 174 # print('其他代码') 175 176 177 #7、主动触发异常raise 异常类型(’异常的内容‘) 178 # 应用于程序中自定义某种法则,一旦不遵循则会像抛出语法异常一样,终止程序的运行 179 180 # print('===>1') 181 # print('===>2') 182 # raise TypeError('类型错误') 183 # print('===>3') 184 # print('===>4') 185 186 187 188 # print('阶段1--->1') 189 # print('阶段1--->2') 190 # print('阶段1--->3') 191 # info=[1,2,3,4,5,6] 192 # 193 # # if len(info) != 7: 194 # # raise ValueError('值的个数 < 7') 195 # assert len(info) == 7 # 我断定len(info) == 7,如果我断言失败,程序则抛出异常 196 # 197 # print('阶段2--->1') 198 # print('阶段2--->2') 199 # print('阶段2--->3') 200 # 201 202 203 #8、 204 # class MyError(BaseException): 205 # def __init__(self,msg): 206 # super().__init__() 207 # self.msg=msg 208 # def __str__(self): 209 # return '<%s>' %self.msg 210 # 211 # raise MyError('我自己定义的异常') 212 213 AGE=100 214 age=input('>>: ').strip() 215 if age.isdigit(): 216 age=int(age) 217 218 if age > AGE: 219 print('too big') 220 221 elif age < AGE: 222 print('too small') 223 else: 224 print('you got it')