异常处理
1.什么是异常:
- 代码发生错误之后,程序就中断了
2.什么是异常处理
- 当代码出现异常时,通过某种方式不让程序中断,合理地跳过去
3.为什么要有异常处理
- 增强用户体验感
- 使代码更有健壮性,容错性
4.异常处理的两种方式
- if else 只能处理简单的异常,如果需要考虑的方面比较多,不适合
- 利用try的方式进行异常处理
5.什么时候用万能处理,什么时候用多分支
- 如果对错误信息不关心,只是想要排除错误让程序继续运行,用万能
- 如果对错误信息要进行明确的分流,让程序多元化开发,用分支
6.错误分类
- 语法错误:这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正
- 逻辑错误
7.具体举例分析
7.1语法错误
if 2 < 3 ---------不加冒号
print("没加冒号")
dic = {"name";"alex"} ----字典冒号换成分隔号
7.2逻辑错误
#用户输入不完整(空),或者输入不是数字,报错
num = input("请示入数字:")
print(int(num))
dic = {"name":"海狗","age":18}
print(dic["hobby"]) #字典的键不存在
7.3异常种类
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
class A:
country = "中国"
def func(self):
pass
foo = A()
print(foo.x)
结果:AttributeError: 'A' object has no attribute 'x'
print(1/0)
结果:ZeroDivisionError: division by zero
num = input("请输入数字:")
if num.isdecimal():
print(int(num)) #我们的正统程序放到了这里,其余的都属于异常处理范畴
elif num.isspace():
print("输入的是空格,执行此处")
elif len(num) == 0:
print("什么都没有,为空执行此处")
else:
print("其他错误,执行这里")
7.4 if 判断处理异常
def foo():
print("正常运行")
dic = {"1":foo}
while True:
choose = input("请输入数字").strip()
if not choose or choose not in dic:
continue
dic[choose]()
break
7.5 异常处理的"私人订制" --try
7.5.1 基本结构
-
try: 被检测的正常代码 except 异常类型: try中一旦检测到异常,就执行这个位置逻辑
-
f = open("text") g = (line.strip() for line in f) for line in g: print(line) else: f.close()
try:
f = open('a.txt')
g = (line.strip() for line in f)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
except StopIteration:
f.close()
next(g)会触发迭代f,依次next(g)就可以读取文件的一行行内容,无论文件text有多大,同一时刻内存中只有一行内容。
提示:g是基于文件句柄f而存在的,因而只能在next(g)抛出异常StopIteration后才可以执行f.close()
7.5.2 异常类只能处理指定的异常情况
s = "hellokity"
try:
int(s) #ValueError
except IndexError as e: #错误类型不对,报错
print(e)
try:
num = int(input("请输入数字:"))#输入不是数字,执行except
dic = {"name":"alex"} #只有num输入数字才执行此处
print(dic["age"]) #执行到就报错
except ValueError: #只捕捉num的错误
print(666)
7.5.3 多分支
try:
num = int(input("请输入数字:")) #输入数字才正确
dic = {"name":"加薪"}
print(dic["age"]) #只能捕捉,查无此键
lst = [1,2,3]
print(lst[11]) #索引超标
print("只要运行到错的就执行except")
except ValueError:
print('输入的有非数字元素')
except KeyError:
print('没有此键')
except IndexError:
print('没有此下标')
print(666)
7.5.4 万能异常捕捉
try:
num = int(input("请输入数字:")) #输入数字才正确
dic = {"name":"加薪"}
print(dic["age"]) #只能捕捉,查无此键
lst = [1,2,3]
print(lst[11]) #索引超标
print("只要运行到错的就执行except")
except Exception as e:
print(e)
print(666)
7.5.5 多分支 加 万能处理
7.5.6 主动抛出异常
try:
raise TypeError('类型错误')
except Exception as e:
print(e)
7.5.7 try except else finally
try:
dic = {"name: "加薪"}
# print(dic['age'])
l1 = [1, 2]
# print(l1[100])
print(111)
except KeyError:
print('没有此键')
except IndexError:
print('没有此下标')
else: #有异常,不执行
print('如果没有出现异常则执行这里')
finally: #一定会执行
print('finally 666')
except 必须依赖于try, else必须依赖于except和try finally只是依赖于try
try:
dic = {"name":"加薪"}
print(dic['age'])
l1 = [1, 2]
print(l1[10])
print(111)
finally: #执行完此句才报错
print('finally 666')
结果:先执行finally语句,后报错
def foo():
try:
print(111)
return 666
finally:
print(888)
print(foo())
#结果:111 888 666
一定注意执行顺序 在return结束函数之前,执行finally代码.
7.5.8 断言:展现一种强硬的态度
# assert 条件
name = "alex"
n1 = input("请输入用户名:")
assert name == n1 #正确执行,错误报错
print(111)
print(222)
assert 1 == 1
# print("断言为真")
assert 1 != 2 #为假报错
print("为真运行")
7.5.9 自定义异常 python中给你提供的错误类型很多,但是不是全部的错误
class AlexError(BaseException):
def __init__(self,msg):
self.msg = msg
def __srt__(self):
return self.msg
try:
raise AlexError("自定义错误类型") #调用__init__
except AlexError as e:
print(e) #调用__str__