#Python 的异常处理
在程序开发过程中,无可避免的需要处理一些异常情况,例如文件被占用导致打开失败、网络拥塞导致传输失败等。为了保障程序正常运行下去,需要进行异常处理。
Python 使用 try
和 except
来捕获异常,并可以使用 finally
指定最终操作:
except
和finally
不是必须的,但是至少要有一个except
可以有多个,分别处理不同类型的异常,发生异常时执行第一个异常类型匹配的except
代码块
try:
try代码块 # 要运行的代码
except 要捕获的异常类型:
except代码块 # try代码块中发生异常时执行
finally:
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 退出了程序,因此这里不会被运行
在这个示例中,程序通过内置函数 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 的一个 内置异常,用于表示除数是零的错误。