鄙人学习笔记
开发工具:Spyder
文章目录
- 异常处理
- 异常
- 异常处理
- 举个例子1
- 举个例子2
- raise语句
- 案例
- 自定义异常
- 案例
异常处理
我们先以一个例子为开头
代码:
控制台输入5,则正常运行:
但如果我们输入xxx, 那么回怎样呢:
python会报错!出现ValueErroe错误.
如果我们输入0,有会怎样呢:
python又报错了!出现ZeroDivisionErroe错误
备注:如果代码出现错误,那么发生错误之后的代码,则不会运行(”后续逻辑…….”没有被打印)
异常
- 定义
异常就是运行时检测到的错误(在有些语言中,比如JAVA,错误和异常是有明确区别的. 但在python中异常和错误的界定不清晰, 我们则可以说错误是一种异常)。
- 现象
当运行时,程序不会再向下执行,而转到函数的调用语句。
比如:
- 常见的异常类型
名称异常(NameError):变量未定义。
类型异常(TypeError):不同类型数据进行运算。
索引异常(IndexError):超出索引范围。
属性异常(AttributeError):对象没有对应名称的属性。
键异常(KeyError):没有对应名称的键。
为实现异常(NotImplementedError):尚未实现的方法。
备注:Exception类为异常基类,是其他所有异常类的父类.
异常处理
为了不让异常影响到之后的程序运行,我们就需要进行异常的处理,“让异常变为正常”。
- 语法
可能触发异常的语句
except 错误类型1 [as 变量1]:
处理语句1
except 错误类型2 [as 变量2]:
处理语句2
except Exception [as 变量3]:
不是以上错误类型的处理语句
else:
未发生异常的语句
finally:
无论是否发生异常的语句
- 作用
将程序由异常状态转为正常流程。
- 说明
子句
含义
as子句
是用于绑定错误对象的变量,可以忽略
except子句
该子句可以有一个或多个,用来捕获某种类型的错误
else子句
该子句最多只能有一个
finally子句
该子句最多只能有一个,如果没有except子句,该子句就必须存在
举个例子1
代码:
异常处理:
运行, 并在控制台输入ss:
由结果可知,经过异常处理后,我们将发生的异常打印的出来,并执行了后面的代码。
如果我们修改一下处理语句,如下所示:
运行一下, 并在控制台先输入xx, 异常被处理后,再故意输入ff:
结果会怎样呢?
会报错!这是因为当person_count = int(input(“请输入人数:”))语句又发生异常时,它找回了调用它的语句div_apple(10)(注意:是except下的div_apple(10)),python发现并没有 try-except的异常处理语句帮他处理,于是他就报错了。
Exception类可以捕获到所有类型的异常。但是如果只写它,我们就不能对具体错误,做出相应的处理逻辑。
如果我们再修改一下处理语句,如下所示:
我们试着运行一下, 并在控制台输入0:
我们再运行一下, 并在控制台输入af:
这样我们就可以对症下药,对具体错误,做出相应的处理。
但是,我们可能不会预测到所有会发生的错误。这时,我们就可以,在末尾加一个Exception捕获剩余错误。
我们修改一下处理语句:
这样就可以既做到对症下药,又做到面面俱到。
举个例子2
我们在处理语句中增加一个else(当没有发生异常时,执行的语句):
我们再运行一下, 并在控制台输入4:
除此之外,还有一个关键字finally(不管有没有异常都执行), 我们测试一下:
我们先在控制台输入一个有错的f:
我们再在控制台输入一个没错的4:
但是我们要是把print(“无论是否发生异常, 都执行的逻辑”)写在处理异常的语句之外(详见下图),这句话也可以执行,那么这个finally到底有啥用呢?
请听下回分解!
raise语句
- 作用
抛出一个错误,让程序进入异常状态。
- 目的
在程序调用层数较深时,向主函数传递错误信息要层层retrun比较麻烦(或者干脆就不能写return)。所以,可以人为抛出异常,直接传递错误信息。
- 图示
假如我们有一个方法fun01,它调用了方法fun02, fun02调用了方法fun03, fun03调用了方法fun04。当我们想用fun04向fun01传递一个信息时,可以层层return,一层一层的传递数据:
但是我们也可以用fun04人为抛出一个异常,直接把信息传递给fun01:
案例
我们创建一个Bunny类,如果创建的Bunny对象的age不符合,大于等于0且小于等于5的要求,我们就抛出异常。
代码:
class Bunny:__slots__ = ("__age")
def __init__(self, age):
self.age = age
def age(self):
return self.__age
.setter
def age(self, value):
if 0 <= value <= 5:
self.__age = value
else:
raise ValueError("非幼年")
try:
b01 = Bunny(6)
print(b01.age)
except Exception as e:
print(e)
结果:
自定义异常
如果python提供的异常类型,并不满足我们的需求,我们就可以自定义异常。
- 语法
定义自定义异常:
class 类名Error(Exception):def __init__(self,参数):
super().__init__(参数)
self.数据 = 参数
调用自定义异常:
try:...
raise 自定义异常类名(参数)
...
except 定义异常类 as 变量名:
变量名.数据
- 作用
封装错误信息
案例
我们在上面一个案例中借用了ValueError异常类型,人为抛出异常,但是我们觉得,并不能满足我们的需求,我们想自己创建一个专用的异常类,抛出错误信息。
创建异常类:
class AgeError(Exception):def __init__(self, msg, age_value):
super().__init__(msg)
self.age_value = age_value
备注:msg表示错误的信息[这是一定要传的参数,并且要传给父类的构造方法], 我们还可以自己传一些想传递的信息,比如:age_value错误的年龄
调用自定义异常类:
class Bunny:__slots__ = ("__age")
def __init__(self, age):
self.age = age
def age(self):
return self.__age
.setter
def age(self, value):
if 0 <= value <= 5:
self.__age = value
else:
raise AgeError("非幼年", value)
创建Bunny类,并处理异常,打印出,异常信息:
try:b01 = Bunny(6)
print(b01.age)
except AgeError as e:
print(e.args)
print(e.age_value)
结果: