国际访客建议访问 Primers 编程伙伴 国际版站点 > Python 教程 > 异常处理 以获得更好的体验。

# Python 的异常处理

在程序开发过程中,无可避免的需要处理一些异常情况,例如文件被占用导致打开失败、网络拥塞导致传输失败等。为了保障程序正常运行下去,需要进行异常处理。

Python 使用 tryexcept 来捕获异常,并可以使用 finally 指定最终操作:

  • exceptfinally 不是必须的,但是至少要有一个

  • except 可以有多个,分别处理不同类型的异常,发生异常时执行第一个异常类型匹配的 except 代码块

try:
    try代码块           # 要运行的代码
except 要捕获的异常类型:
    except代码块        # try代码块中发生异常时执行
finally:
    finally代码块       # 无论如何都会执行
graph TD
    START([开始]) --> try代码块 -- 异常 --> except代码块 --> END[(结束)]
    try代码块 -- 正常 --> finally代码块 --> END([结束])

示例:

运行示例

print("开始")

try:
    # 打开文件
    # __file__ 是一个特殊的内置变量,表示当前 Python 文件自身的路径
    fp = open(__file__)  

    # 尝试向文件中写入内容,因为文件是以只读方式打开的,因此会出错
    fp.write("hello")        
   
except Exception as e:          # 捕获 Exception 类型的异常,赋值给 e
    print("捕获到异常", e)

    # 进行错误处理 ...

    quit()      # 退出程序
finally:
    # 在最终操作中关闭文件,确保无论是否发生异常,文件都会被正确关闭
    print("最终处理")
    fp.close()                  

print("结束")   # 异常发生时调用 quit 退出了程序,因此这里不会被运行

在这个示例中,程序通过内置函数 open,以只读方式打开了一个文件,然后尝试向该文件写入内容。

由于文件是以只读方式打开的,写入时会产生 io.UnsupportedOperation 异常。

except Exception as e 捕获到了这个异常,将其赋值给了变量 e。在这个代码块里可以进行相关的错误处理。示例中选择了调用 quit 退出程序。

最后,尽管调用了 quit,程序仍会运行到 finally 代码块中。示例程序在这里进行文件关闭,以确保无论是否产生异常,文件都会正确关闭。

Exception 类型是所有 内置异常 的基类(不含系统退出类异常),因此可以用于捕获所有 内置异常(不含系统退出类异常)。

你可能暂时还不知道“基类”是什么,但请暂时放下,将在后面的 面向对象 章节中学习。

# 多个捕获流程

except 可以有多个,发生异常时按顺序进行捕获,用于分别处理不同类型的异常。

例如:

运行示例

print("开始")

try:
    # 打开文件
    fp = open("一个不存在的文件")   
except ZeroDivisionError as e:  # 捕获 ZeroDivisionError 类型的异常,赋值给 e
    print("捕获到 ZeroDivisionError 类型的异常", e)
except FileNotFoundError as e:  # 捕获 FileNotFoundError 类型的异常,赋值给 e
    print("捕获到 FileNotFoundError 类型的异常", e)
except Exception as e:          # 捕获 Exception 类型的异常,赋值给 e
    print("捕获到 Exception 类型的异常", e)

print("结束")   # 异常发生时调用 quit 退出了程序,因此这里不会被运行

在这个示例中,程序通过内置函数 open,打开一个不存在的文件。

因此产生了 FileNotFoundError 类型的异常,即文件不存在。后续 except FileNotFoundError as e 将会捕获到该异常。

因为并没产生 ZeroDivisionError 类型的异常,所以 except ZeroDivisionError as e 不会捕获到异常。

虽然 Exception 可以捕获 FileNotFoundError 类型的异常,但是异常已经被 except FileNotFoundError as e 捕获了,因此 except Exception as e 不会捕获到异常。

# 抛出异常

异常本身就是一个变量,通过 raise 关键字进行抛出。

通过 raise 抛出的异常类型必须是 BaseException 的派生类。

自定义异常时,通常继承 Exception

你可能暂时还不知道“基类”,“派生类”,“继承”是什么,但请暂时放下,将在后面的 面向对象 章节中学习。

运行示例

print("开始")

try:
    # 输入一个整数作为除数
    n = int(input('请输入一个整数:'))

    # 检查除数是否为 0,如果为 0 则抛出异常
    if n == 0:
        raise ZeroDivisionError("除数不可以为0")

    # 进行除法计算
    print(10 / n)
except Exception as e:        # 捕获 Exception 类型的异常,赋值给 e
    print("捕获到异常", e)
finally:
    print("最终处理")                

print("结束")

在这个示例中,程序通过输入获得一个整数。使用该整数作为除数,进行除法运算。

在执行除法之前,程序对除数的值进行了检查。因为除数不可用为 0,所以程序在发现 n 的值是 0 时通过 raise 抛出了一个 ZeroDivisionError 类型的异常。

后续 except Exception as e 会捕获到该异常并打印。

ZeroDivisionError 是 Python 的一个 内置异常,用于表示除数是零的错误。

本文 更新于: 2025-11-27 09:37:56 创建于: 2025-11-27 09:37:56