Skip to content

异常处理:让程序更健壮

在编写程序时,我们都希望程序能够顺利运行,不出任何差错。但实际情况是,程序在运行过程中可能会遇到各种各样的问题,导致程序崩溃。这些问题,我们称之为异常 (Exception)

异常处理就像是给程序穿上了一件“防护服”,当程序遇到问题时,能够优雅地处理这些异常,而不是直接崩溃。通过异常处理,我们可以让程序更加健壮,提高用户体验。

那么,什么是异常处理呢? 简单来说,异常处理就是预先设定好一些应对方案,当程序在运行过程中遇到错误时,能够按照我们预先设定的方案来处理,而不是直接停止运行。

Python 提供了 try...except...else...finally 这样的语句块来实现异常处理。

1. try 块:尝试执行的代码

try 块包含可能引发异常的代码。你可以把它理解为“尝试做某件事,但可能会出错”。

python
try:
    # 可能会引发异常的代码
    result = 10 / 0  # 这里会引发 ZeroDivisionError 异常
    print(result)
except:
    # 处理所有类型的异常
    print("发生错误了!")

在这个例子中,10 / 0 会引发 ZeroDivisionError 异常,因为除数不能为零。 如果不使用 try...except 语句,程序会直接崩溃。

2. except 块:捕获并处理异常

except 块用于捕获特定类型的异常,并提供相应的处理代码。 可以理解为“如果发生了某种错误,就执行这里的代码”。

python
try:
    num = int(input("请输入一个整数:"))
    result = 10 / num
    print("结果是:", result)
except ZeroDivisionError:
    print("除数不能为零!")
except ValueError:
    print("请输入一个有效的整数!")

在这个例子中,我们使用了两个 except 块,分别处理 ZeroDivisionErrorValueError 异常。 如果用户输入了 0,就会捕获 ZeroDivisionError 异常;如果用户输入的不是整数,就会捕获 ValueError 异常。

指定异常类型:

except 后面可以指定要捕获的异常类型。 如果不指定,则会捕获所有类型的异常(就像上面的第一个例子)。 建议尽可能指定具体的异常类型,这样可以更精确地处理错误,避免捕获到不应该捕获的异常。 Python 中常见的异常类型包括:

  • ZeroDivisionError: 除零错误
  • TypeError: 类型错误
  • ValueError: 值错误
  • IOError: 输入/输出错误
  • IndexError: 索引错误
  • KeyError: 键错误 (用于字典)
  • FileNotFoundError: 文件未找到错误 (Python 3.6+)

使用 as 获取异常对象:

except 语句还可以使用 as 关键字来获取异常对象。 通过异常对象,我们可以获取更详细的错误信息。

python
try:
    # 一些代码
    open("nonexistent_file.txt", "r")
except FileNotFoundError as e:
    print("文件未找到:", e) # 打印更详细的错误信息

3. else 块:没有异常时执行

else 块在 try 块中没有发生任何异常时执行。 可以理解为“如果没有发生任何错误,就执行这里的代码”。

python
try:
    num = int(input("请输入一个整数:"))
    result = 10 / num
except ZeroDivisionError:
    print("除数不能为零!")
except ValueError:
    print("请输入一个有效的整数!")
else:
    print("结果是:", result) # 如果没有发生错误,才打印结果

在这个例子中,只有当用户输入了有效的整数,并且没有发生除零错误时,才会执行 else 块,打印计算结果。

4. finally 块:总是执行

finally 块包含的代码无论是否发生异常,都会被执行。 通常用于清理资源,例如关闭文件、释放连接等。 可以理解为“无论是否发生错误,都要执行这里的代码”。

python
file = None
try:
    file = open("my_file.txt", "r")
    content = file.read()
    print(content)
except FileNotFoundError:
    print("文件未找到!")
finally:
    if file:
        file.close() # 确保文件总是被关闭

在这个例子中,无论是否成功打开文件,finally 块中的 file.close() 都会被执行,确保文件被正确关闭,防止资源泄露。

try...except...else...finally 语句块的执行顺序如下:

  1. 首先执行 try 块中的代码。
  2. 如果在 try 块中发生了异常:
    • 如果存在匹配的 except 块,则执行该 except 块中的代码。
    • 如果没有匹配的 except 块,则异常会传递到上一层调用者。
  3. 如果没有发生异常,则执行 else 块中的代码。
  4. 无论是否发生异常,最后都会执行 finally 块中的代码。

掌握异常处理是编写健壮 Python 程序的重要一步。合理使用 try...except...else...finally 语句块,可以有效地处理程序中可能出现的各种异常,提高程序的稳定性和可靠性。