1.异常的定义 *****
2.异常的分类
3.异常的组成
4.常见异常
5.异常的处理 *****
6.主动抛出异常 raise关键字
7.断言
8.自定义异常 as关键字
9.总结 使用场景
"""
什么是异常?
异常是错误发生前的一种信号
如果没有人来处理这个信号 程序就会中断执行并抛出错误信息
异常的分类:
1.语法异常
如果是编译器 会自动提示
如果是文本编辑器 在你运行代码前 解释器会检查语法
2.运行时异常(逻辑异常)
这种异常只有在代码被执行时才能发现
1. 当我们可以预知程序发生错误的条件,应该用if判断去规避错误
AGE=10
age=input('>>: ').strip()
if age.isdigit():
age=int(age)
if age > AGE:
print('too big')
else:
print('必须输入数字')
2. 当我们无法预知程序发生错误的条件,也就是说错误一定会发生,那么我们应该
try..except去补救
异常的组成
1.追踪信息 (具体发生异常的位置 以及函数的调用顺序)
2.异常的类型 (错误的类型)
3.异常的消息 (详细的错误信息)
排除错误时 先查看异常类型和详细信息
最后根据追踪信息找到发生的位置进行修改
我们之所以学习异常处理
为的是让我们的程序更加稳定 (健壮性) 不容易崩溃
多种异常类型处理
万能异常类型 except Exception 或BaseException 基于OOP的继承和多态
raise主动抛出异常 raise 异常类型(消息) 类型必须是Exception的子类
当用户使用时没有按照规范使用
常和if连用,作为if的结果 raise TypeError("你输入的不是整型!")
assert断言 一个条件跟表达式 结果必须是bool类型
后续的功能需要前面的某个条件成立 才能执行
if len(li) < 1:
raise ValueError("列表中没有数据!")
等同于assert len(li) > 0
assert 就是为了简化代码,但是没有具体的自定义消息
自定义异常类 系统提供的异常类 和我们想要买描述的错误 不匹配时
语法:用一个class 继承BaseException
class UnlikeError(BaseException):
def __init__(self,msg):
self.msg = msg
# except UnlikeError as e: #e作为异常错误的对象
# print(e.text)
使用finally:无论是否发生异常 都会执行finally 可以用来回收系统资源!
finally:
print("关闭文件!")
f.close()
使用场景:
无法预知错误发生的原因时 或者知道为什么但是程序无法解决时
不应该滥用try except
(乱用会导致代码可以读变差)
什么时候用? 如果你知道为什么出错 应该把代码修改正确 而不是加上try except
你不清楚为什么会发生异常! 这时候用try
"""
"""
语法:
try:
被检测的子代码块
except 异常类型1 as e:(e是别名,为了访问异常对象里的内容)
匹配成功异常类型1,执行的子代码块
except 异常类型2 as e:
匹配成功异常类型2,执行的子代码块
except 异常类型3 as e:
匹配成功异常类型3,执行的子代码块
...
except Exception(BaseException) as e:
万能异常
else:
被检测的子代码块没有发生异常时执行的代码块
finally:
无法被检测的子代码块有无异常发生,都会执行,
通常应该在这里进行回收资源的操作
"""
"""
常见的发生原因:
NameError 找不到这个名字 要么变量 要么函数
ValueError 在调用一个函数时给的的值不正确
TypeError 类型错误 例如字符串与数字加减乘除 调用一个不能被调用的类型
ZeroDivisionError 除数不能为0
KeyError 没有这个key
IndexError 索引不存在
StopIteration 没有更多的值可以迭代
FileNotFoundError 文件不存在
io.UnsupportedOperation 文件的操作不支持
AttributeError 没有这个属性
KeyboardInterrupt 程序被强行终止 ctrl+c
"""
多种异常类型处理
print("staring.....")
try:
# name
# [][-1]
1/0
pass
except NameError:
print("名字找不到!")
except IndexError:
print("索引超出范围")
except ZeroDivisionError:
print("除数不能为0")
print("end.......")
当代码可能出现多种异常时的写法2
except (NameError,IndexError,ZeroDivisionError):
上面两种写法 都可以处理多种异常 但是 异常类型太多了 不可能全写完
万能异常类型 Exception 或BaseException 基于OOP的继承和多态
print("staring.....")
try:
{}["aaa"]
name
[][-1]
1/0
except Exception:
print("可能名字找不到! 可能所以超出范围 可能除数为0")
print("end.......")
使用finally来回收资源
try:
f = open(r"D:\上海python全栈4期\day31\异常处理\1今日内容","rt",encoding="utf-8")
f.read()
# f.write("123")
except Exception:
print("发生异常了")
finally:
print("关闭文件!")
f.close()
print(f.closed)
"""
raise主动抛出异常
当程序中有一些限制 然而用户没有遵守 我们可以主动抛出异常
语法:
raise 异常类型(异常的详细信息)
类型必须是BaseException的子类
"""
age = input("请输入整型的年龄:")
if not age.isdigit():
raise TypeError("你输入的不是整型!")
age = int(age)
print("十年后你%s岁" % (age + 10))
"""
assert断言 可以理解断定 就是很清楚 很明确
什么时候需要断定?
下面的代码必须依赖上面代码的正确数据
语法: assert 结果为Bool的表达式
如果值为True 则继续往下执行
为False 抛出一个 AssertionError 表示断言失败
没有assert 也可以使用if来玩 assert 仅仅是简化了代码
"""
第一部分代码 负责产生一个列表
li = []
li.append(1)
li.append(2)
这里一定要确保数据是有效的
if len(li) < 1:
raise ValueError("列表中没有数据!")
assert len(li) > 0
需要使用列表中的数据来完成任务 如果没有数据无法完成
print(li[0])
print(li[0])
print(li[0])
"""
当系统提供的这些异常类型 和你要描述的错误不匹配时 就需要自定义异常类型
写法:
class 自定义异常类型名称(BaseException):
总结一下:之所以自定义异常类型 是为了更具体描述你的错误 让使用者一眼就看出了
关键点:1.如何自定义异常类型
2.在except中 使用as 来获取异常对象
"""
你随便输入一句话 看我喜不喜欢 不喜欢我就抛出异常
自定义异常类
class UnlikeError(BaseException):
def __init__(self,msg):
self.msg = msg
text = input("输入一段话:")
if text == "你真帅":
print("你说得对!")
else:
raise UnlikeError("你再看看...")
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)