Python 程序设计 - 22. 异常处理
1. 引入
在开发程序时,难免会遇到各种错误和异常情况。例如,文件读取失败、用户输入无效、网络请求出错等等。为了提高程序的稳定性和可靠性,我们需要学会处理这些错误,以确保程序能够在出现问题时正确地处理,而不是直接崩溃。
Python 提供了异常处理机制,可以通过 try、except、else 和 finally 来捕获和处理异常。在本节中,我们将深入了解 Python 的异常处理机制,并通过实例讲解如何使用它来提高程序的健壮性。
2. 异常处理的基本概念
在 Python 中,程序在执行过程中可能会抛出错误或异常。我们可以使用异常处理机制来捕获这些错误并进行相应的处理。这样,程序在出现错误时不会崩溃,而是能优雅地处理错误。
常见的异常类型
| 异常类型 | 描述 |
|---|---|
ZeroDivisionError | 除零错误 |
ValueError | 值错误,通常是传入的参数类型不正确 |
FileNotFoundError | 文件未找到错误 |
IndexError | 列表索引越界错误 |
TypeError | 类型错误 |
KeyError | 字典中找不到指定键的错误 |
异常处理语法
Python 使用 try、except、else 和 finally 来处理异常,基本结构如下:
try:
# 可能会抛出异常的代码
except ExceptionType as e:
# 异常处理代码
else:
# 如果没有异常,执行这部分代码
finally:
# 无论是否抛出异常,都会执行的代码(常用于资源释放)
3. 异常处理的基本用法
(1)捕获异常
最常见的用法是使用 try 和 except 来捕获可能发生的异常,并进行相应的处理。except 可以捕获特定类型的异常。
语法
try:
# 可能出错的代码
except ExceptionType:
# 异常发生时执行的代码
案例:
try:
x = 1 / 0 # 除零错误
except ZeroDivisionError:
print("发生除零错误!")
输出:
发生除零错误!
(2)捕获多种异常
你可以通过多个 except 语句来捕获不同类型的异常,或者使用一个 except 语句捕获多个异常。
语法
try:
# 可能出错的代码
except (ExceptionType1, ExceptionType2):
# 异常发生时执行的代码
案例:
try:
x = int("abc") # 值错误
except (ZeroDivisionError, ValueError) as e:
print(f"发生错误: {e}")
输出:
发生错误: invalid literal for int() with base 10: 'abc'
(3)使用 else 语句
else 语句在 try 语句块没有抛出异常时执行。else 语句通常用于在没有异常的情况下执行一些后续代码。
语法
try:
# 可能出错的代码
except ExceptionType:
# 异常发生时执行的代码
else:
# 如果没有异常,执行的代码
案例:
try:
x = 5 / 2
except ZeroDivisionError:
print("发生除零错误!")
else:
print(f"计算结果是:{x}")
输出:
计算结果是:2.5
(4)使用 finally 语句
finally 语句中的代码不管是否发生异常都会被执行,通常用于释放资源、关闭文件等操作。
语法
try:
# 可能出错的代码
except ExceptionType:
# 异常发生时执行的代码
finally:
# 无论是否有异常,都会执行的代码
案例:
try:
f = open("test.txt", "r")
content = f.read()
except FileNotFoundError:
print("文件未找到!")
finally:
print("执行完毕,无论是否发生异常!")
输出:
文件未找到!
执行完毕,无论是否发生异常!
4. 异常的传递与自定义异常
(1)异常的传递
异常不仅可以在 try 块内捕获,也可以向上层传递。例如,如果一个函数内发生异常,但没有处理,则会传递给调用该函数的地方。
案例:
def divide(a, b):
return a / b
try:
result = divide(5, 0)
except ZeroDivisionError:
print("除零错误!")
输出:
除零错误!
(2)自定义异常
Python 允许你定义自己的异常类型。自定义异常通常继承自 Exception 类。
语法
class CustomError(Exception):
pass
try:
raise CustomError("这是一个自定义错误")
except CustomError as e:
print(f"捕获到自定义异常: {e}")
案例:
class NegativeNumberError(Exception):
def __init__(self, message):
self.message = message
super().__init__(self.message)
def check_positive(number):
if number < 0:
raise NegativeNumberError("数字不能为负数")
return number
try:
check_positive(-1)
except NegativeNumberError as e:
print(f"捕获到异常: {e}")
输出:
捕获到异常: 数字不能为负数
5. 总结与练习题
在本节中,我们学习了 Python 中的异常处理机制,包括如何捕获和处理常见的异常类型,如何使用 try、except、else 和 finally 来构建健壮的程序。此外,我们还学习了如何自定义异常并处理异常的传递。
通过使用异常处理,程序能够优雅地应对运行时错误,避免程序崩溃,并提供更好的错误信息。
6. 练习题(不少于 3 题)
练习 1
编写一个程序,要求用户输入一个数字,并将其转换为整数。如果输入的不是数字,程序应捕获 ValueError 并提示用户重新输入。
练习 2
编写一个程序,打开一个文件 data.txt,如果文件不存在,则捕获 FileNotFoundError 错误并提示用户文件未找到。
练习 3
编写一个程序,定义一个函数 divide(a, b),计算两个数相除,并在除数为零时抛出一个 ZeroDivisionError 异常。
练习 4
编写一个程序,捕获 IndexError 异常,并在列表访问越界时打印错误信息。
7. 练习题答案
答案 1
while True:
try:
num = int(input("请输入一个数字: "))
break
except ValueError:
print("输入无效,请输入一个有效的数字!")
答案 2
try:
with open("data.txt", "r") as f:
content = f.read()
except FileNotFoundError:
print("文件未找到!")
答案 3
def divide(a, b):
if b == 0:
raise ZeroDivisionError("除数不能为零!")
return a / b
try:
result = divide(5, 0)
except ZeroDivisionError as e:
print(f"捕获到异常: {e}")
答案 4
lst = [1, 2, 3]
try:
print(lst[5])
except IndexError:
print("列表索引越界!")
通过这些练习,你已经掌握了如何处理异常并使程序更加健壮。希望你能在实际开发中灵活运用异常处理,增强程序的稳定性和用户体验。
评论区