异常处理
1.什么是异常?
在程序执行的过程中,出现错误,导致程序无法执行完毕,就称为异常。当异常发生时,python解释器会打印异常详细信息,并且终止程序的运行。
2.如何排查错误?
1.定位到错误发生的位置
I.程序没有调用任何内置模块和方法,那么错误发生的位置一定在最后一行。
II.如果程序调用系统内置模块,一定是自己的代码在调用时发生了错误;如果调用的是别人的模块,那么有可能是别人的代码有问题,按照追踪信息进行查看。
2.查看异常类型 例:IndexError
3.查看异常的信息(值)例:list index out of range
3.异常的组成部分:1.追踪信息;2.异常类型;3.异常的值
# 常见异常
- AttributeError 试图访问一个对象没有的属性,比如foo.x,但是foo没有属性x
- IOError 输入/输出异常;无法打开文件或无法读写
- ImportError 无法引入模块或包;基本上是路径问题或名称错误
- SyntaxError Python语法错误异常,代码不能编译
- IndentationError 缩进异常;代码没有正确缩进
- IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
- KeyError 试图访问字典里不存在的键
- KeyboardInterrupt Ctrl+C被按下
- NameError 使用一个还未被赋予对象的变量
- TypeError 传入对象类型与要求的不符合
- UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
- ValueError 传入一个调用者不期望的值,即使值的类型是正确的

# a = # SyntaxError: invalid syntax 语法错误 # age # NameError: name 'age' is not defined 名字不存在 #open("asasasas") # FileNotFoundError: [Errno 2] No such file or directory: 'asasasas' 路径错误 # f = open("1.今日内容") # f.close() # f.read() #ValueError: I/O operation on closed file. 文件已经关闭 你还要去读写 #f = open("1.今日内容",mode="rt",encoding="utf-8") #f.write("123") # io.UnsupportedOperation: not writable 不能写入数据 读写模式错误导致 #int("abc") # ValueError: invalid literal for int() with base 10: 'abc' 数据的值错误导致 # def func(): # print(1) # print(2) # IndentationError: unexpected indent 缩进错误 li = [] li[1] # IndexError: list index out of range 索引不存在 # dic = {} # dic["name"] # KeyError: 'name' key不存在
4.异常的分类:可以由发生的时间不同分为两类。
1.语法错误(语法检测异常)
解释器在执行代码前会先检测语法,检测通过才会开始执行。如果语法出现异常,代码一行都不会执行。
a = # File "E:/PY文件/异常处理/aaa.py", line 2 # a = # ^ # SyntaxError: invalid syntax
2.逻辑错误(运行时异常)
已经通过语法检测,在解析执行期间发生的异常。
print('start') a = int('abc') print('stop') # start # Traceback (most recent call last): # File "E:/PY文件/异常处理/aaa.py", line 4, in <module> # a = int('abc') # ValueError: invalid literal for int() with base 10: 'abc'
5.异常的语法:
1.语法1:try except 异常类型
2.语法2:try 多个except 异常类型
3.语法3:try except 万能异常(Exception)
4.语法4:try except Exception as e:(万能异常取别名) print(e) 注:一定要输出异常的值。
5.语法5:try 多个except 异常类型 最后跟上万能异常。(先捕获能够明确的异常类型,最后捕获万能异常类型。)
6.语法6:try except else(else只有在程序正常运行,没有发生异常时才会执行其中代码。)
7.语法7:try except finally(无论程序会不会发生异常,都会执行finally其中的代码。)
总结:如果能够明确知道异常发生的原因,就不要产生异常,使用if进行判断;如果不知道异常发生的原因,但是知道异常的类型,那就明确捕获该类型的异常;如果不知道发生的原因,也不知道异常的类型,可以使用万能异常,但是一定要打印异常信息。

# print("start") # # a = int("abc") # # print("over") li = [] # # 语法1 # try: # # 把可能发出错误的代码放到try中 # print("start") # # a = int("abc") # li[1] # print("over") # # except ValueError: # # 当try中真的发生了错误 就会执行 except中的代码 # # 在这里可以做一些补救措施 # print("发生了 ValueError异常") # # print("over") # # 语法2 except可以有多个 # try: # # 把可能发出错误的代码放到try中 # print("start") # a = int("abc") # li[1] # print("over") # # except ValueError: # # 当try中真的发生了错误 就会执行 except中的代码 # # 在这里可以做一些补救措施 # print("发生了 ValueError异常") # except IndexError: # print("发生了 IndexError 索引不正确") # print("over") # 语法4 万能异常 Exception类 尽量少用 可能会导致 程序既不报错 也不正常运行 无法定位错误位置 # try: # # 把可能发出错误的代码放到try中 # print("start") # # a = int("abc") # # li[1] # 10 / 0 # dic = {} # dic["name"] # print("over") # # except Exception: # print("可能是任何类型的错误 反正是发生错误了") # print("over") # 语法5 万能异常 Exception类 建议 输出异常的值 # try: # # 把可能发出错误的代码放到try中 # print("start") # # a = int("abc") # # li[1] # 10 / 0 # dic = {} # dic["name"] # print("over") # # # 可以通过给异常取别名 来获取异常的对象 对象中包含了错误信息 # except Exception as e: # print("可能是任何类型的错误 反正是发生错误了") # print(e) # print(type(e)) # print("over") # # 语法6 先捕获能够明确的异常类型 最后捕获万能异常类型 # try: # # 把可能发出错误的代码放到try中 # print("start") # # a = int("abc") # # li[1] # # 10 / 0 # dic = {} # dic["name"] # print("over") # except ValueError: # print("值不对.....") # except ZeroDivisionError: # print("除数不能为0") # # 可以通过给异常取别名 来获取异常的对象 对象中包含了错误信息 # except Exception as e: # print("可能是任何类型的错误 反正是发生错误了") # print(e) # print(type(e)) # # print("over") # 语法7 try except else # try: # # 把可能发出错误的代码放到try中 # print("start") # # a = int("abc") # # li[1] # # 10 / 0 # dic = {} # # dic["name"] # print("over") # except ValueError: # print("值不对.....") # except ZeroDivisionError: # print("除数不能为0") # # 可以通过给异常取别名 来获取异常的对象 对象中包含了错误信息 # except Exception as e: # print("可能是任何类型的错误 反正是发生错误了") # print(e) # print(type(e)) # else: #当没有发生异常会执行else 只能except的后面 # print("执行了else") # print("over") # 语法8 try except finally # try: # # 把可能发出错误的代码放到try中 # print("start") # # a = int("abc") # # li[1] # # 10 / 0 # dic = {} # # dic["name"] # print("over") # except ValueError: # print("值不对.....") # finally: #无论是否发生异常 最后都会执行finally中的代码 # print("finally") # print("over") import io # finally的使用场景 可以用finally来执行一些清理操作 类似__del__ try: print("start") f = open("1.今日内容","rt",encoding="utf-8") f.read() print("end") except FileNotFoundError: print("文件路径错误...") except io.UnsupportedOperation: print("文件不能被写入....") finally: f.close() print(f.closed)
6.自定义异常类
当我们的程序,使用者去使用时,没有按照我们的要求操作时,就会导致程序出错,而且我们无法帮助使用者处理这种错误时,就可以主动抛出异常。
主动抛出异常:raise 关键字,后面跟任意Exception类型的子类。
# 自定义异常类型 class LoginException(Exception): pass def login(): name = input("username:").strip() pwd = input("password:").strip() if name == "blex" and pwd == "123": print("登录成功!") else: raise LoginException("用户名或密码不正确....") login()
7.断言
断言指的是一段代码,要执行,必须确定某个条件一定成立。断言可以简化代码,assert后面一个bool类型的表达式,结果为True,则会执行代码。断言的缺点是异常的类型时固定的,并且不能指定异常信息。
names = [] assert 1 print("正在处理这堆数据....") print("正在处理这堆数据....") print("正在处理这堆数据....")