python核心阶段(六)—— 异常处理

发布时间:2023年12月18日

1.错误和异常的概念

?1.1 错误

? 错误是指无法通过其他代码进行处理的问题,主要包括语法错误和逻辑错误

语法错误:比如定义函数写成了dfe xxx(),这种错误可以通过解释器给出的提示修改

逻辑错误:语法层面没问题,但自己设置的逻辑出了问题,例如判定成年时 一> 小于18岁成年

?1.2 异常?

? 异常是指程序在执行过程中, 出现的未知错误。其语法和逻辑都正确可以通过其他代码进行处理

例如:设置了一个计算器,结果后续使用时,用户输入了 x ÷ 0? (if语句判定一下除数不能为0)

? ? ? ? ? ?列表或字典中,索引时输入了不存在的位置量

2.常见的系统异常

异常类型异常名称错误示例
除0异常ZeroDivisionError1 / 0
名称异常NameErrorsz
类型异常TypeError“1” + 2
索引异常IndexErrorl = [1, 2]
l[3] (只有两个元素,访问第三个)
键异常KeyErrordic = {"name": "sz", "age": 18}
dic["add"]
值异常ValueErrorint("abc")
属性异常AttributeErrorname = "sz"
print(name.xx)
迭代器异常StopIterationit = iter([1, 2])
print(next(it))
print(next(it))
print(next(it))

注:所有系统异常也有对应的继承关系树,一般如下:

系统异常类继承树

3.异常解决方案

?3.1 预防

? ?异常预防的主要方案是进行容错处理,但弊端是可能会造成代码过多,过于混乱;而且只有一部分异常可以通过这个方式来解决,有些异常解决不了(例如名称异常)

?3.2 解决

解决异常的主要方案是捕获处理异常

  • ?方案一:try语句

? ? ? ? 语法: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("捕捉完毕,程序继续执行...")

  • 方案二:?with语句

? ? ? ?作用:适用于执行某一段代码A之前, 进行预处理, 执行代码A结束后, 进行清理操作

? ? ? ? ? ? ? ? ? 这是因为如果代码运行过程中出现异常,就会立刻崩溃停止,不进行清理,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 而使用这个语句无论代码是否异常都会清理

? ? ? ?原理:相当于在代码前后分别执行了?__enter__()和__exit__()
?

? ? ? ?语法:with + 内容表述 + as xxx(可省略):

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?要执行的语句体

?

with open("xx.jpg","r") as f:
    f.readlines()

# 虽然会报错,因为jpg文件需要用二进制方法打开,但是最后会执行关闭文件的代码

?

4.手动抛出异常

在实际操作中,我们还可以根据需求设置手动异常,即:通过 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)

5.自定义异常

? ? ?在异常类继承树中,所有的内置异常及自定义异常都继承自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)

文章来源:https://blog.csdn.net/m0_61766362/article/details/134930928
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。