八、异常处理

1. 异常的概念

异常是指程序运行的过程中出现了错误,也叫Bug。

案例一:

# 定义人类
class Person:
    # 属性 姓名
    name = None
    # 属性 年龄
    age = None
print(Person().sex)

执行结果:

image-20240723162348318

案例二:

print(2 / 0)

执行结果:

image-20240723162510866

0是不能作为被除数的,所以程序也出异常了。

2. 异常捕获与处理

如果出现程序异常,我们不去捕获和处理,那么程序遇到异常,就直接终止,后续的代码无法继续执行,这将是可怕的事情。 Python提供了完善的异常处理机制,可以实现捕获异常,处理异常,最终实现代码继续运行下去。从而 让程序具有极好的容错性,让程序更加的健壮

使用try...except捕获异常

基本语法:

try:
	可能会有异常的代码
except:
	出现异常的执行代码

示例:

try:
    print(2 / 0)
except:
    print("出现了异常")
print("异常被捕获,程序继续执行")

执行结果:

出现了异常
异常被捕获,程序继续执行

经过上面的处理,程序不会中断。

捕获指定的异常

try:
    print(2 / 0)
except ZeroDivisionError as z:
    print("出现了异常")
print("程序继续")

执行结果:

出现了异常
程序继续

多个except:

class Person:
    # 属性 姓名
    name = None
    # 属性 年龄
    age = None
# 多个except
try:
    print(Person().sex)
except ZeroDivisionError as e:
    print("出现了除0异常")
except AttributeError as a:
    print("出现属性异常")
print("程序继续")

执行结果:

出现属性异常
程序继续

捕获所有异常,BaseException异常类是所有异常类的基类(老祖宗类),所有异常类都是直接或者间接继承BaseException异常类,Exception类是继承BaseException,并且有很多具体实现,大部分的异常类直接继承Exception,所以我们一般开发用Exeption。

try:
    print(2 / 0)
except Exception as e:
    print("出现了异常")
print("程序继续")

多异常捕获

假如程序块可能出现异常的种类比较多,我们可以用多异常捕获,只要出现其中一个异常,就会捕获到。

语法:

try:
	可能会有多种异常的代码
except (异常1,异常2...异常N)
	出现异常的执行代码

示例:

try:
    print(Person().sex)
except (ZeroDivisionError, AttributeError):
    print("出现了除0异常或者属性异常")
except:
    print("出现了未知异常")
print("程序继续")

执行结果:

出现了除0异常或者属性异常
程序继续

else块

在Python的异常处理流程中还可添加一个else块,当 try块没有出现异常时,程序会执行else块。例如如下程序:

try:
    print(2 / 1)
except:
    print("出现了异常")
else:
    print("else块")
    print("1")
print("程序继续")

执行结果:

2.0
else块
1
程序继续

finally块

在异常处理中,finally块中的代码无论是否出现异常,都会执行。 有些时候,程序在try块里打开了一些物理资源(例如数据库连接、网络连接和磁盘文件等),这些物理资源都必须被显式回收

try:
    print(2 / 0)
except:
    print("出现了异常")
else:
    print("没有出现异常,我们做一些操作")
finally:
    print("无论是否有异常,都会执行")
print("程序继续")

执行结果:

出现了异常
无论是否有异常,都会执行
程序继续

3. 使用raise引发异常

当程序出现错误时,系统会自动引发异常。除此之外,Python也允许程序自行引发异常,自行引发异常使用raise 语句来完成。

一般是业务逻辑上,业务异常问题,我们可以自行引发异常。

语法格式: raise [exceptionName [(reason)]]

案例:

try:
    age = 17
    if age < 18:
        raise Exception
    else:
        print("放行")
except Exception as e:
    print(type(e))

执行结果:

<class 'Exception'>

4. 自定义异常类

实际开发中,有时候系统提供的异常类型不能满足开发的需求。这时候你可以通过创建一个新的异常类 来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承。

示例:

class TooLongException(Exception):
    def __init__(self, length):
        self.lenght = length
    def __str__(self):
        return f"长度是{self.lenght},超长了"
def name_test():
    try:
        name = input("请输入您的姓名:")
        if len(name) > 4:
            raise TooLongException(len(name))
        else:
            print(name)
    except TooLongException as tle:
        print("出现异常,", tle)
name_test()

执行结果:

请输入您的姓名:家里好舒服
出现异常, 长度是5,超长了

5. 异常的传递性

异常是具有传递性的,假如方法A调用方法B,方法B调用方法C,如果方法C代码出现异常,并且没有处理异常,则会传递给方法B,同理,如果B依然没有处理异常,则最终传递给方法A。

示例:

def funC():
    print("funC开始")
    a = 1 / 0
    print("funC结束")
def funB():
    print("funB开始")
    funC()
    print("funB结束")
def funA():
    print("funA开始")
    funB()
    print("funA结束")
try:
    funA()
except Exception as e:
    print(e)

执行结果:

funA开始
funB开始
funC开始
division by zero
最近一次更新 3/20/2025, 7:54:12 AM