14. 异常处理

一、什么是异常

程序在运行过程之中,不可避免的出现一些错误,比如:使用了没有赋值的变量、使用了不存在的索引、除 0 等等。这些错误在程序中,我们称之为异常。程序运行过程中,一旦出现异常将会导致程序立即终止,异常以后的代码全部都不会执行。

二、异常的传播

当在函数中出现异常时,如果在函数中对异常进行了处理,则异常不会继续传播。如果函数中不会对异常进行处理,,则异常会继续向函数调用处传播。如果函数调用处处理了异常,则不再传播,如果没有则继续向调用处传播。直到传递到全局作用域(主模块),如果依然没有处理,则程序终止,并显示异常信息。

当程序运行过程中出现异常以后,所有的异常信息会被保存在一个专门的异常对象,而异常传播时,实际上就是异常对象抛给了调用处。比如,ZeroDivisionError 类的对象专门用来表示除 0 的异常,NameError 类的对象专门用来处理变量错误的异常。在 Python 中提供了多个异常对象。

python 复制代码
def fun1():
    a  = 10 / 0

def fun2():
    fun1()

def fun3():
    fun2()

fun3()

三、异常处理机制

程序运行时出现异常,目的并不是让程序直接终止。Python 是希望在出现异常时,我们可以编写代码来对异常进行处理。遇到异常时,Python 中有两种处理机制。

3.1、try...except机制

在 Python 中,提供 try...catch 语句捕获并处理异常。在使用时,把可能产生异常的代码放在 try 子句中,把处理结果放在 except 子句中。这样,当 try 子句中的代码块出现异常时,就会执行 except 语句块中的内容。如果 try 语句块中代码没有异常,那么 except 语句块不会执行。这样我们就可以通过代码来处理异常,避免因为一个异常导致整个程序的终止。

我们还可以在原有的基础上在添加一个 else 子句,用于指定当 try 语句块中没有出现异常时要执行的语句块。该语句块中的内容当 try 语句中发现异常时,将不被执行。

我们还可以在添加一个 finallty 子句。该子句中的代码无论是否发生异常都会被执行。

python 复制代码
try:
    代码块(可能出现异常的代码)
except [异常名 [as 异常对象名]]:
    代码块(出现错误以后的处理方式)
[else:
    代码块(没出现时要执行的语句)]
[finally:
    代码块(无论是否出现异常,该子句都会执行)]

如果 except 后面不跟任何内容,则此时它会捕获所有的异常。

python 复制代码
print("异常处理之前")

try:
    # try中放置的是可能错误的代码
    print(10/0)
# 如果except后不跟任何内容,此时它会获取所有的错误
except:
    # except中放置的是出现以后的处理代码
    print("出现异常")
# 这是一个可选的结构,表示没有出现异常要执行的代码
else:
    print("程序正常异常,没有错误")
# 这是一个可选结构,表示无论是否出现异常,最后都要执行的语句
finally:
    print("无论是否出现异常,该子句都会执行")

print("异常处理之后")

如果 except 后面跟者异常类型,那么该类型对应的异常。我们还可以在在异常类后面跟着一个 as xxx,此时 xxx 就是异常对象。

python 复制代码
try:
    # try中放置的是可能错误的代码
    print(10/0)
    print(a)
    1 + "hello"
# 如果except后不跟着异常的类型,那么它只会捕获该类型对应的异常
# 可以在异常类后面跟着一个 as xxx,此时xxx就是异常对象
except NameError as e:
    # except中放置的是出现以后的处理代码
    print("出现NameError")
    print(e)
except ZeroDivisionError as e:
    # except中放置的是出现以后的处理代码
    print("出现ZeroDivisionError")
    print(e)
# Exception 是所有异常类的父类
# 如果except后跟的是 Exception,它会捕获所有的异常
except Exception as e:
    print("未知异常")
    print(e)

在使用 try...except语句捕获异常时,如果在 except 后面不指定异常名称,则表示捕获全部异常;

在使用 try...except语句捕获异常时,当程序出现异常并处理完后,程序继续执行;

我们可以在 except 语句后面使用一对小括号将可能出现的异常名称括起来,多个异常之间使用逗号分隔。

3.2、raise机制

如果某个函数或方法可能会产生异常,但不想在当前函数或方法中处理这个异常,则可以使用 raise 语句在函数或方法中抛出异常。

python 复制代码
raise [异常类型名[异常描述]]

如果异常类型名为可选参数,它用于指定抛出的异常名称以及异常信息的相关描述。如果省略,就会把当前的错误原样抛出。异常描述也可以省略,如果省略,则在抛出异常时,不附带任何描述信息。

python 复制代码
def div(a,b):
    if b == 0:
        # raise用于向外部抛出异常
        # 后面可以根一个异常类,或异常类的对象
        raise ZeroDivisionError("除0异常")
    return a/b

print(div(10,0))

四、自定义异常类

我们也可以自定义异常类,只需要创建一个类继承 Exception 类即可。

python 复制代码
class MyException(Exception):
    pass
相关推荐
汤姆yu33 分钟前
基于python的化妆品销售分析系统
开发语言·python·化妆品销售分析
上去我就QWER1 小时前
Python下常用开源库
python·1024程序员节
程序员杰哥2 小时前
Pytest之收集用例规则与运行指定用例
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·pytest
Jyywww1213 小时前
Python基于实战练习的知识点回顾
开发语言·python
朝朝辞暮i3 小时前
从0开始学python(day2)
python
程序员黄同学3 小时前
Python中的列表推导式、字典推导式和集合推导式的性能和应用场景?
开发语言·python
AI小云4 小时前
【Python高级编程】类和实例化
开发语言·人工智能·python
道之极万物灭4 小时前
Python uv虚拟环境管理工具详解
开发语言·python·uv
高洁014 小时前
【无标题】大模型-模型压缩:量化、剪枝、蒸馏、二值化 (2
人工智能·python·深度学习·神经网络·知识图谱