? 错误是指无法通过其他代码进行处理的问题,主要包括语法错误和逻辑错误
语法错误:比如定义函数写成了dfe xxx(),这种错误可以通过解释器给出的提示修改
逻辑错误:语法层面没问题,但自己设置的逻辑出了问题,例如判定成年时 一> 小于18岁成年
? 异常是指程序在执行过程中, 出现的未知错误。其语法和逻辑都正确,可以通过其他代码进行处理
例如:设置了一个计算器,结果后续使用时,用户输入了 x ÷ 0? (if语句判定一下除数不能为0)
? ? ? ? ? ?列表或字典中,索引时输入了不存在的位置量
异常类型 | 异常名称 | 错误示例 |
---|---|---|
除0异常 | ZeroDivisionError | 1 / 0 |
名称异常 | NameError | sz |
类型异常 | TypeError | “1” + 2 |
索引异常 | IndexError | l = [1, 2] l[3] (只有两个元素,访问第三个) |
键异常 | KeyError | dic = {"name": "sz", "age": 18} dic["add"] |
值异常 | ValueError | int("abc") |
属性异常 | AttributeError | name = "sz" print(name.xx) |
迭代器异常 | StopIteration | it = iter([1, 2]) print(next(it)) print(next(it)) print(next(it)) |
注:所有系统异常也有对应的继承关系树,一般如下:
? ?异常预防的主要方案是进行容错处理,但弊端是可能会造成代码过多,过于混乱;而且只有一部分异常可以通过这个方式来解决,有些异常解决不了(例如名称异常)
解决异常的主要方案是捕获处理异常
? ? ? ? 语法:try:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?可能会出现异常的代码
? ? ? ? ? ? ? ? ? ?except + 要捕捉的异常类别:?若想详细知道错误, 可加上:as xxx,下面print一下即可
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 对于这个异常的处理
? ? ? ? ? ? ? ? ? ?else: (可以省略)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 没出现异常时做的处理
? ? ? ? ? ? ? ? ?? finally:(可以省略)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 不管有没有出现异常, 都会执行的代码
? ? ? ? ?
? ? ? ? ? 注意:1)try语句后面的代码不管会抛出多少个异常, 只会从上往下检测, 检测到第一个后,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 就立即停止进行下一步?
? ? ? ? ? ? ? ? ? ? ?2)except语句可以重复写多个,用于分别捕获多种异常;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 同一个except语句中也能以元组形式写多个异常类别,用于同时捕获多种异常;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 如果不知道错误的具体类型,可以输入:Exception
? ? ? ? ? ? ? ? ? ? ?3)else语句一定要放在except语句后面,finally语句一定要放到最后
try:
abc # 只会捕捉第一个错误
1 + "2"
except ZeroDivisionError as xiangxi:
print("出现除零异常",xiangxi)
except(TypeError,NameError) as juti:
print("出现类型或名称异常",juti)
else:
print("内容无异常")
finally:
print("捕捉完毕,程序继续执行...")
? ? ? ?作用:适用于执行某一段代码A之前, 进行预处理, 执行代码A结束后, 进行清理操作;
? ? ? ? ? ? ? ? ? 这是因为如果代码运行过程中出现异常,就会立刻崩溃停止,不进行清理,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 而使用这个语句无论代码是否异常都会清理
? ? ? ?原理:相当于在代码前后分别执行了?__enter__()和__exit__()
?
? ? ? ?语法:with + 内容表述 + as xxx(可省略):
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?要执行的语句体
?
with open("xx.jpg","r") as f:
f.readlines()
# 虽然会报错,因为jpg文件需要用二进制方法打开,但是最后会执行关闭文件的代码
?
在实际操作中,我们还可以根据需求设置手动异常,即:通过 raise 语句直接抛出相关类型的异常
# 利用raise语句手动抛出错误
def set_age(age):
if age <= 0 or age >= 200:
raise ValueError("值出现错误,年龄输入应符合常理")
else:
print("张三的年龄为:",age)
set_age(-18)
# 利用try语句捕捉错误
try:
set_age(-18)
except ValueError as e:
print("值出现错误,年龄输入应符合常理",e)
? ? ?在异常类继承树中,所有的内置异常及自定义异常都继承自Exception类,故如果我们想自定义一个异常类,应该要继承自Exception类
class LessZero(Exception):
def __init__(self,message,error_code):
self.message = message # 接收错误信息
self.ec = error_code # 接收错误代码
def __str__(self):
return self.message + str(self.ec)
pass
def set_age(age):
if age <= 0:
raise LessZero("年龄不应该比零小,错误代码:", 520) #传递错误信息,代码
else:
print("张三的年龄为:",age)
set_age(-18)