第二十二节课:异常
1 # 第23节课:异常 2 ''' 3 本节概述: 4 1- 异常的概念 5 2- 异常的产生 6 3- 异常的捕获和处理 7 4- 函数调用战法 8 5- 自定义异常 9 ''' 10 # 1- 异常的概念:就是报错.代码执行产生错误,无法继续 11 # a = 8956 / 0 12 # print (a) #打印报错:ZeroDivisionError: division by zero 13 # b = [1,2] 14 # c = b[2] 15 # print(c+39) #打印报错:IndexError: list index out of range 16 # 理解异常: 17 # *当解释器遇到错误的,无法执行的代码 18 # *中断当前代码的执行,抛出一个异常对象 19 # sdfsdf #直接执行报错:NameError: name 'sdfsdf' is not defined 20 # NameError是异常对象的一种 21 # *开发者还可以自己定义异常对象 22 # *形形色色的异常,标识了不同的错误 23 # 例子: 24 # *输入0会导致当前程序异常退出 25 # while True: 26 # num = input('input a number:') 27 # print('100 / %s = %s' % (num,100.0/int(num))) 28 # 希望的行为:1.程序不要退出 2.提示用户输入错误 3.继续让用户重新输入数字,继续执行 29 # if过滤:事前处理.可处理已知的bug,如除数输入0是已知的 30 # 异常处理属于事后处理 即问题已经出现了,要去解决不让代码因报错而停止.可以有适当提示. 31 32 # 3- 异常的捕获和处理 33 # while True: 34 # num = input('input a number:') 35 # try: 36 # print('100 / %s = %s' % (num,100.0/int(num))) 37 # except ZeroDivisionError: #捕获一种异常,这种异常是已知的 38 # print ('除数不能为0') 39 # except ValueError: 40 # print('只能输入数字哦!') #捕获多种异常 41 42 ''' 43 捕获后得到详细的异常信息: 44 try: 45 ohmy 46 except NameError as e: 47 print('handle NameError:',e) 48 # e 就是异常对象 49 # 我们可以打印出储存里面储存的具体错误信息 50 ''' 51 # 怎么打印报错具体信息实例: 52 # while True: 53 # num = input('input a number:') 54 # try: 55 # print('100 / %s = %s' % (num,100.0/int(num))) 56 # except ZeroDivisionError as e: #捕获一种异常,这种异常是已知的 57 # print ('除数不能为0') 58 # print( e) #打印得报错具体信息:handle NameError: float division by zero 59 # except ValueError as v: 60 # print('只能输入数字哦!') #打印得:invalid literal for int() with base 10: 'x' 61 # print(v) 62 # except Exception: #查看可知这个Exception是前面两个异常类的父类.也可直接写作: 63 # except: #表示不管有什么错误,都执行冒号以后的操作 64 # except Exception as ree: 65 # print('异常了,这个异常是前面两种异常都没有抓到的其它异常',ree) 66 '''''' 67 ''' 68 ZeroDivisionError 指明专门捕获ZeroDivisionError异常 69 NameError 指明专门捕获NameError异常 70 对应的处理代码区块 71 执行结果 72 是NameError 而不是 ZeroDivisionError 73 ''' 74 # 怎么知道异常信息? 75 # import traceback 76 # while True: 77 # num = input('input a number:') 78 # try: 79 # print('100 / %s = %s' % (num,100.0/int(num))) 80 # except : 81 # print ('除数不能为0\n'+ traceback.format_exc()) 82 # #如果输入的值不是数字,就会打印:ValueError: invalid literal for int() with base 10: 'b' 83 # #如果输入的数字是0.则会打印:ZeroDivisionError: float division by zero 84 # else: #注:如果前面抓到异常,else语句不执行,如果没有抓到异常才会执行这一句 85 # print('no exception之后就得放这个else,必须放在所有except代码块后面,finally之前') 86 # finally:#不管有没有抓到异常都会执行finally语句 87 # print('try except代码块的结束,要放finally语句') 88 89 # 4- 函数调用栈: 90 ''' 91 1.文件读操作.txt .log 文件不存在会直接报错 92 fo=open('gfre') 93 2.异常机制使用场景: 94 boss布置任务:十个自动化测试用例的测试 95 小明如果跑到第三个出问题卡了,就得修好第三个之后才能跑下面的,如果有异常机制,就可以略过第三个就跑下面的. 96 直接跑完十个用例,然后反馈那几个有问题再针对性地修 97 **函数的调用:从上往下调用--类似于公告的发布 98 **异常的抛出:从下往上 --类似于事故的上报 99 **看报错信息: 100 1.如果调用第三方库的方法,控制台第一个 2.根本错误原因在最后一个信息。 所以看到很多个报错不要慌,因为都是最后一个报错才是根本原因 101 ''' 102 # 1. 103 # fo=open('gfre') #直接报错了:FileNotFoundError: [Errno 2] No such file or directory: 'gfre' 104 # try: 105 # fo = open('gfre') 106 # except: 107 # print('请检查文件路径') 108 109 # # 异常的报错顺序: 110 # def f3(): #相当于区 111 # print('in f3 - begin') 112 # b=4/0 113 # print('in f3 - end') 114 # def f2(): #相当于市 115 # print('in f2 - begin') 116 # f3() 117 # print('in f2 - end') 118 # def f1(): #相当于省 119 # print('in f1 - begin') 120 # try: 121 # f2() 122 # except: 123 # print('f2报错了') 124 # print('in f1 - end') 125 # f1() #相当于北京 126 # 这里如果要加异常机制,不应在f3源头里面加,比如代码:fo = open('gfre')是open报错的,不可能让开发团队去把open函数的代码改了。买彩票,不可能自己写个数字去让彩票官方团队去把中奖号码写成你的号码 127 ''' 128 以下是报错信息:可能函数本身没错,所以,谁调用抛给谁,一层一层往上抛.f1报错,是f2导致的--> 129 抛给f2.f2报错是f3导致的-->抛给f3.f3报错是某一行代码导致的.揪出这行代码.这是一个连锁反应 130 Traceback (most recent call last): 131 File "C:/Users/86199/Desktop/python/第23节课异常.py", line 118, in <module> 132 f1() 133 File "C:/Users/86199/Desktop/python/第23节课异常.py", line 116, in f1 134 f2() 135 File "C:/Users/86199/Desktop/python/第23节课异常.py", line 112, in f2 136 f3() 137 File "C:/Users/86199/Desktop/python/第23节课异常.py", line 108, in f3 138 b=4/0 139 ZeroDivisionError: division by zero 140 in f1 - begin 141 in f2 - begin 142 in f3 - begin 143 Process finished with exit code 1 144 ''' 145 146 # 5- 自定义异常 147 # **继承至Exception *注意,一定要继承Exception这个类才是异常类 148 # class NameTooLongError(Exception): 149 # pass 150 # class NameTooShortError(Exception): 151 # pass 152 # # **使用raise抛出: 153 # raise NameTooLongError 154 # **抛出异常使用场景: 155 # *********函数出现错误,代码无法正常运行的情况下 156 # *********告诉上册调用代码,什么样执行错误产生了 157 # *********由上层代用代码决定如何处理 158 # # 自定义异常实例: 159 # class NameTooLongError(Exception): 160 # err ='name.long' 161 # print('名字太长了') 162 # def methFun(self): 163 # pass 164 # class NameTooShort(Exception): 165 # err ='name.short' 166 # print('名字太短了!') 167 # def methFun(self): 168 # pass 169 # def inputName(): 170 # name=input('请输入用户名:') #5-10 171 # if len(name) > 10: 172 # raise NameTooLongError #自定义的异常要自行抛出来 173 # elif len(name) < 5: 174 # raise NameTooShort 175 # try: 176 # inputName() 177 # except NameTooLongError: 178 # print('您输入的名字太长了!') 179 # except NameTooShort as ns: 180 # print('您输入的名字太短了!',ns.err) 181 # ns.methFun() 182 183 # # 还可以自定义抛异常: 184 # for one in range(0,5): 185 # if one == 3: 186 # exit() #这里退出的话,就不打印后面那句话了 187 # raise ValueError('这是我的自定义异常') 188 # print(one) 189 # ###exit()不跑异常,直接退出 190 191 # # 断言:assert---检查点-----如果后续代码比较重要,而且很依靠前面的数据或者状态 192 # tel = input('请输入手机号:') 193 # assert len(tel) ==11,'手机位数有误!' 194 # print('我在处理手机运营商操作') #这就是断言,如果手机位数是11位,就是正常的,如果位数不对,就报错:AssertionError: 手机位数有误! 195 # # 断言和if是有区别的:if只是报错,没有挂掉,而断言是报错之后挂掉