三、异常的传递3.1概念:异常的传递——当函数/方法执行出现异常,会即将异常 传递给函数/方法的调用一方,如果传递到主程序仍然没有异常处理,程序才会被终止。 3.2需求:
代码出现异常,异常传递过程情况1:一个函数 代码: def demo1(): return int(input('请输入一个整数:'))print(demo1()) 错误执行结果: 错误信息是一个值错误,int无法转换d,其实真正出现错误的代码在第二行也就是转换整数的时候出现了错误,第二行代码出现问题的时候会把异常交给第五行代码,第五行代码是在调用demo1这个函数,把这个异常交到了主程序print(demo1()),而这个主程序并没有做异常处理,所以主程序才会被终止。 代码出现异常,异常传递过程情况2:嵌套函数 代码:
错误执行结果: 流程理解: 整数转换时出现了错误,出现错误的代码仍然是第二行,当第二行代码出现错误后会把异常交给第六行,这行带妈妈是在demo2函数内部调用demo1函数,当异常被传递到demo2之后并没有在demo2函数内部处理异常,既然没有处理异常就会把这个异常继续向上传递,传递给代码的第九行,第九行是在主程序中调用demo2这个函数。 这个就是异常一级一级传递的过程,如果某个函数出现了异常,会把这个异常向上传递,传递给这个函数的调用一方,一直传递到主程序之后如果发现异常没有被处理程序才会被终止。 3.3异常的传递在开发中用处:问题思考: 在开发中如果想保证每个函数的正常运行,在开发时在每个函数内部就会大量的增加捕获异常的代码,试想如果每个函数内部都需要增加捕获异常的代码,程序员在开发的时候就会太辛苦了,需要增加大量的代码。 那么怎么减轻这种工作量呢? 答: 因为出现异常之后会从函数中一层一层的传递到主程序中,那么就可以利用异常的传递性,在主程序中捕获异常。 修改代码如下: def demo1(): return int(input('请输入一个整数:'))def demo2(): return demo1()# 利用异常的传递性,在主程序中捕获异常try: print(demo2())except Exception as result: print('未知错误 %s' % result) 错误执行结果:捕获到了异常 3.4总结:在开发中,可以在主函数中增加异常捕获,而在主函数中调用的其他函数,只要出现异常,都会传递到主函数的异常捕获中,这样就不需要在代码中增加大量的异常捕获,能够保证代码的整洁。 四、抛出异常4.1 主动抛出异常的应用场景在开发中,除了代码执行出错,Python解释器会抛出异常之外,还可以根据应用程序特有的业务需求主动抛出异常。 示例: 需求:提示用户输入密码,如果长度少于8,抛出异常 注意: 当前函数只负责提示用户输入密码,如果密码长度不正确,需要其他函数进行额外处理。因此可以抛出异常,由其他需要处理的函数捕获异常。 4.2 主动抛出异常在python中提供了一个Exception异常类,在开发时如果满足特定业务需求时,希望抛出异常,可以:
需求:
代码1:看代码整体是否可以跑完,异常代码最后再写
执行结果:当输入密码长度>=8时 执行结果:当输入密码长度<8时 为什么会输出一个None? 因为input_password函数没有做任何的返回,没有任何的返回在用input函数进行输出的时候就会在控制台输出一个空对象None. 代码2:完整版 在创建Exception对象时,PyCharm 会给我们提示信息,*args代表多值元组参数 ,所以在创建异常对象时可以传递一下异常的描述信息。 def input_password(): # 1.提示用户输入密码 pwd = input('请输入密码:') # 2. 判断密码长度 >=8 ,返回用户输入的密码 if len(pwd) >= 8: return pwd # 3. 如果<8,主动抛出异常 print('主动抛出异常') # > 1.创建一个Exception的对象,可以使用错误信息字符串作为参数 ex = Exception('密码长度不够') # > 2.使用raise关键字抛出异常对象 raise ex# 提示用户输入密码try: print(input_password())except Exception as result: print(result) 执行结果:密码长度正确时 执行结果:密码长度错误时 在创建Exception对象时,输入了错误信息字符串作为参数,之后在调用一方捕获异常时直接输出就可以把创建异常对象指定的异常信息输出在控制台。 |
|