Python之路(九)——Python 异常处理
本节内容
本文参考自:https://docs.python.org/3/tutorial/errors.html
- 错误与异常
- 内置异常
- 处理异常
- 引发异常
- 自定义异常
- 异常善后工作
- 内置善后机制
一、错误与异常
错误(Error):无法通过其他代码来进行修正,只能修改原程序。包含:语法错误,逻辑错误
- 语法错误:不符合语言的语法规范,导致程序无法启动。这类错误Python解释器会提示。例如:函数定义没有加'()'、if 条件语句后没有写':' 等等
- 逻辑错误:程序没有语法错误,而是业务逻辑处理出现问题,导致没有得到相应的效果。这类错误解释器无法感知,通常需要程序员Debug原代码 进行跟踪梳理
异常(Exception):程序没有明显错误,但在运行时会导致程序崩溃,即会受到运行环境的影响。这些可以通过编写额外代码(非业务逻辑内,仅处理异常)来进行干涉,保证程序正常运行。例如:用户交互获取的数据无法识别、网络请求失败等等。通常有两类方式进行处理:
- 强制判断: 多重IF-ELIF...ELSE。问题:①业务逻辑与异常判断、处理逻辑混编,可读性差 ②因为异常出现由运行环境决定,非必然。强制判断增加程序无效运行
- 解释器检测:try...except 。解释器最清楚程序运行环境,一旦出现异常立刻跳转异常处理程序。好处:① try内写业务逻辑,except 内写处理异常。增加可读性 ②及时响应,而非硬性判断,增加程序运行效率
二、内置异常
Python针对异常专门定义了BaseException ,即异常基类。所有的异常都是此类或者其子类的实例。例如:
- NameError: name 'spam' is not defined
- ZeroDivisionError: division by zero
- TypeError: Can't convert 'int' object to str implicitly
更多:猛点这里
注意:用户定义的异常类,继承自Exception,而不建议BaseException
三、处理异常
分析
- 执行 x = ...语句,用户输入为正常(可转换为整数),不执行异常处理程序(except块内程序),继续执行 break 跳出循环,完毕
- 执行 x = ...语句,输入异常,例如:输入abc,跳转 异常处理程序,打印:Oops!..... 。继续循环提示用户输入
- 执行 x = ...语句,输入异常,例如:命令行下 ctrl + c。 此时的异常不是except 能捕捉的异常类型,异常交由解释器,现象:报错(追踪信息、异常类名、异常消息)
多异常情况
多异常优先触发按顺序触发
打印: DCB。如果 except B放置第一位,则打印: BBB,so通常子异常类放置在前,父异常类在后
注意: 这里也提供缺省的 "except : " 形式。一般不建议书写。
异常可以使用别名
注意被捕获对象
注意:使用else子句比向try子句添加其他代码要好,因为它可以避免意外捕获一个没有被try…except语句保护的代码引发的异常
四、引发异常
解释器可以抛出异常,有时需要程序员自主引发一个异常,可自定义异常信息。
处理完异常,同时又不想内部消化掉,就需要在except 中raise。例如: 捕获一个异常(NameError,msg='HiThre')只是想记录到日志文件中,那么要在except 中继续抛出异常。
五、自定义异常
用户可以自定义自己的异常类,继承自Exception
例如:想对本系统中的所有业务异常进行统一管理,最简单的方式:定义一张表有异常编码,异常消息 两列。出现异常程序员手动抛出自定义异常类及其编码。这样至少可以解决异常消息提示的硬编码问题。
六、异常善后工作
有时无论异常有没有发生都需要做的事情,通俗理解为"打扫战场"。例如:打开一个文件完成读操作。
try: f = open('1.txt','r') print("文件读取中....") except FileNotFoundError: print("文件没有找到") finally: print("无论是否异常都需要做文件关闭") f.close()
七、内置善后工作
Python对一些常用操作内置了善后工作。例如:利用with(内置实现了 enter exit方法) 上下文打开一个文件,离开with前一定销毁(自动)了这个文件句柄