3279

16 分钟

#Python 的异常处理

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

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

  • exceptfinally 不是必须的,但是至少要有一个
  • except 可以有多个,分别处理不同类型的异常,发生异常时执行第一个异常类型匹配的 except 代码块
try: try代码块 # 要运行的代码 except 要捕获的异常类型: except代码块 # try代码块中发生异常时执行 finally: finally代码块 # 无论如何都会执行

异常

正常

开始

try代码块

except代码块

结束

finally代码块

示例:

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 退出了程序,因此这里不会被运行

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

在这个示例中,程序通过内置函数 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 退出了程序,因此这里不会被运行

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

在这个示例中,程序通过内置函数 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("结束")

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

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

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

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

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

创建于 2025/5/7

更新于 2025/6/11