一.异常是什么
什么是异常?
异常就是错误发生前的一种信号
如果没有人来处理这个异常 程序就会中断执行并抛出错误信息
异常的分类:
1.语法检查异常 这种异常时最低级异常 绝不应该犯(犯了就可能卷铺盖走人了)
也非常好避免
如果是编译器 会自动提示
如果是文本编辑器 在你运行代码前 解释器会检查语法
2.运行时异常(逻辑异常)
这种异常只有在代码被执行时才能发现
我们要处理的重点就是运行时异常
特点:在没有运行代码前 是无法发现的
如果运行异常已经发生并且没有正确处理他,就抛出错误信息
并且中断程序的执行 这是要我们学校异常解决的问题
异常的组成
1.追踪信息(具体发生异常的位置 以及函数的调用顺序)
2.异常的类型(错误的类型)
3.异常的消息(详细的错误信息)
我们之所以学习异常处理
为的是让我们的程序更加稳定(健壮性)不容易崩溃
name=
def func():
import xxaaa
def func1():
func()
func1()
二.常见异常
常见异常及发生原因:
NameError 找不到这个名字 要么变量 要么函数
ValueError 在调用一个函数时给的值不正确
TypeError类型错误 例如字符串与数字加减乘除 调用一个不能被调用的类型
ZeroDivisionError 除数不能为0
KeyError 没有这个key
IndexError 索引不存在
StopIteration 没有更多的值可以迭代
FileNotFoundError 文件不存在
io.UnsupportedOperation 文件的操作不支持
AttributeError 没有这个属性
KeyboardInterrupt 程序被强行终止 ctrl+c
三 异常处理
要处理异常
要学的就是一个新的语法
今后使用最多的写法:
try:
这里放可能出现异常的代码
except:异常的类型
当异常发生并且异常类型匹配时
执行except中的代码
注意:一旦try中有代码抛出了异常 后面的代码全都不执行
练习:捕获某种类型的异常 捕获任意类异常 感受一下执行顺序
基本语法
print("starting....")
try:
name
except NameErrop:
ptint("名字找不到")
print("end......")
多种异常类型处理
print("staring......")
try:
name
[][-1]
pass
except NameError:
print("名字找不到")
except IndexError:
print("索引超出范围")
print("end......")
当代吗可能出现多种异常时的写法
print("staring.......")
try:
#name
[][-1]
1/0
pass
except NameError:
print("名字找不到!"
except IndexError:
print("索引超出范围")
except ZeroDivisionError:
print("除数不能为0")
print("end......")
当代码可能出现多种异常时的写法
print("staring......")
try:
#name
#[][-1]
1/0
pass
except NameError:
print("名字找不到!")
except IndexError:
print("索引超出范围")
except ZeroDivisionError:
print("end.......")
当代码可能出现多种异常时的写法2
print("staring.....")
try:
{}["aaa"]
#name
[][-1]
1/0
except (NameError,IndexError,ZeroDivisionError):
print("可能名字找不到! 可能所以超出范围 可能除数为0")
print("end.......")
上面两种写法 都可以处理多种异常 但是 异常类型太多了 不可能全写完
万能异常类型 Exception 或BaseException 基于OOP的继承和多态
print("staring.....") try: #{}["aaa] #name #1/0 except Exception: print("可能名字找不到!可能所以超出范围 可能除数为0") print("end.......")
五.不太常用的语法
语法1
try:
except:
else: try中没有发生异常时执行
语法2
try:
except:
finally:无论是否发生异常 都会执行finally 可以用来回收系统资源!
print("start...")
try:
#1/0
[][1]
pass
except ZeroDivisionError:
print("除数异常")
else:
print("else会在 try中没有异常时被执行")
print("end...")
finally
print("start...")
try:
#1/0
#[][1]
pass
except ZeroDivisionError:
print("除数异常")
except IndexError:
print("索引异常")
else:
print("else 会在 try中没有异常时执行")
finally:
print("finally 无论异常是否发生 都会执行!)
print ("end...")
#使用finally来回收资源
try: f=open(r"D:上海Python全栈4期day31异常处理1今日内容","rt",encoding="utf-8") #f.write("123") except Exception: print("发生异常了") finally: print("关闭文件") f.close() print(f.closed)
六.主动抛出异常
当程序中有一些限制 然而用户没有遵守 我们可以主动抛出异常
语法:
raise 异常类型(异常的详细信息)
类型必须是BaseException的子类
#raise NameError("这就是名字不存在的异常!")
age = input("请输入整型的年龄:")
if not age.isdigit():
raise TypeError("你输入的不是整型!")
age = int(age)
print("十年后的你%s岁%(age+10))
七 断言
断言可以理解为断定 很清楚 很明确
什么时候需要断定?
下面代码必须依赖上面代码的正确数据
语法:assert 结果为Bool的表达式
如果值为True 则继续往下执行
为False 抛出一个 AssertionError 表示断言失败
没有assert 也可以使用if来玩 assert 仅仅是简化了代码
第一步分解代码 负责产生一个列表
li = []
li.append(1)
li.apppend(2)
这里一定要确保数据有效的
if len(li)<1:
raise ValueError("列表中没有数据")
assert len(li)>0
#需要使用列表中的数据来完成任务 如果没有数据无法完成
print(li[0])
八.自定义异常类型
当系统提供的这些异常类型 和你要的描述错误不匹配是 就需要自定义异常类型
写法:
class 自定义异常类型名称(BaseException):
总结一下:之所以自定义异常类型 是为了更具体描述你的错误 让使用者一眼能看出来
关键点:1.如何自定义异常类型
2.在except中 使用as 来获取异常对象
#你随便输入一句话 看我喜不喜欢 不喜欢我就抛出异常
class UnlikeError(BaseException):
def __init__(self,msg,text):
self.msg = msg
self.text = text
#函数中可能抛出异常
def hello():
text = input("输入一段话:")
if text =='你真帅':
print('有眼光!')
else:
raise UnlikeError("你再想想","另一个参数")
#捕获异常
try:
hello()
#获取异常对象
except UnlikeError as e:
print (e.text)
九.使用场景
try:
print("业务逻辑分层复杂 写了好几百行!")
except Exception:
print("可能是文件不存在!")
try:
print("业务逻辑分层复杂 写了好几百行!")
except Exception:
print("类型不匹配!")
print("业务逻辑分层复杂 写了好几百行!")
print("业务逻辑分层复杂 写了好几百行!")
print("业务逻辑分层复杂 写了好几百行!")
print("业务逻辑分层复杂 写了好几百行!")
print("业务逻辑分层复杂 写了好几百行!")
print("业务逻辑分层复杂 写了好几百行!")
print("业务逻辑分层复杂 写了好几百行!")
print("业务逻辑分层复杂 写了好几百行!")
print("业务逻辑分层复杂 写了好几百行!")
print("业务逻辑分层复杂 写了好几百行!")
print("业务逻辑分层复杂 写了好几百行!")
print("业务逻辑分层复杂 写了好几百行!")
except Exception:
print("有点问题!")
# 不应该滥用try except
# 什么时候用? 如果你知道为什么出错 应该把代码修改正确 而不是加上try except
# 你不清楚为什么会发生异常! 这时候用try
try:
f = open("xxxx","rt")
f.read()
except Exception:
print("文件不存在!")