11.Python异常:捕获异常、异常的传递

Python 的异常处理机制通过 try、except、else 和 finally 语句来捕获和处理运行时异常。了解如何捕获异常、如何传递异常以及如何自定义异常类是 Python 异常处理的关键。下面详细介绍 Python 异常的捕获和传递。

1. 捕获异常 (Exception Handling)

1.1 基本的异常捕获

使用 try...except 语句可以捕获并处理程序运行时可能发生的异常。捕获到异常后,可以在 except 块中执行相应的处理逻辑。

try:
    x = 10 / 0  # 会抛出除零错误
except ZeroDivisionError as e:
    print(f"捕获到异常:{e}")  # 捕获并处理 ZeroDivisionError
1.2 捕获多个异常

一个 try 块中可以捕获多种类型的异常,具体的异常类型需要在不同的 except 语句中进行处理。

try:
    # 假设这里可能会引发 ValueError 或 ZeroDivisionError
    x = int("abc")  # 会抛出 ValueError
    y = 10 / 0  # 会抛出 ZeroDivisionError
except ValueError as e:
    print(f"ValueError 异常:{e}")
except ZeroDivisionError as e:
    print(f"ZeroDivisionError 异常:{e}")
1.3 捕获所有异常

如果需要捕获所有异常类型,可以使用 Exception 类(所有异常的基类)来捕获。

try:
    # 可能会抛出任何异常
    x = 10 / 0
except Exception as e:
    print(f"捕获到异常:{e}")
1.4 使用 else 子句

else 子句是 try...except 语句的一部分,它会在没有异常发生时执行。如果 try 块中的代码没有引发异常,则会执行 else 中的代码。

try:
    x = 10 / 2  # 没有异常
except ZeroDivisionError as e:
    print(f"捕获到异常:{e}")
else:
    print(f"计算结果是:{x}")
1.5 使用 finally 子句

finally 块用于在异常发生与否时,执行一些资源清理工作,如关闭文件、数据库连接等。无论是否发生异常,finally 块的内容都会执行。

try:
    f = open("test.txt", "r")
    content = f.read()
except FileNotFoundError as e:
    print(f"文件未找到:{e}")
else:
    print(content)
finally:
    f.close()  # 无论是否发生异常,都确保文件关闭

2. 异常的传递 (Exception Propagation)

2.1 异常向上传递

try 块中的代码引发异常后,如果异常没有被当前函数处理,它会向上层函数传播。直到遇到处理该异常的 except 块或程序终止。

def func1():
    print("In func1")
    raise ValueError("Error in func1")

def func2():
    print("In func2")
    func1()

try:
    func2()
except ValueError as e:
    print(f"捕获到异常:{e}")
输出:
In func2
In func1
捕获到异常:Error in func1
2.2 自定义异常

你可以自定义异常类并在代码中抛出自定义异常。自定义异常通常用于表示程序中的特定错误类型。

class MyError(Exception):
    pass

def func():
    raise MyError("这是自定义异常")

try:
    func()
except MyError as e:
    print(f"捕获到自定义异常:{e}")
2.3 异常链 (Exception Chaining)

有时我们需要在捕获某个异常后抛出一个新的异常,并将原始异常信息保留。使用 raise ... from 可以在抛出新异常时保留原始异常。

def func1():
    raise ValueError("这是原始异常")

def func2():
    try:
        func1()
    except ValueError as e:
        raise RuntimeError("这是新的异常") from e  # 保留原始异常

try:
    func2()
except RuntimeError as e:
    print(f"捕获到异常:{e}")
    print(f"原始异常:{e.__cause__}")
输出:
捕获到异常:这是新的异常
原始异常:这是原始异常

3. 抛出异常 (Raising Exceptions)

有时你可能希望主动抛出异常,以便让调用方捕获和处理。你可以使用 raise 关键字手动抛出异常。

def check_age(age):
    if age < 18:
        raise ValueError("年龄必须大于或等于18")
    return f"年龄 {age} 合法"

try:
    print(check_age(16))
except ValueError as e:
    print(f"捕获到异常:{e}")

4. 总结

  • 捕获异常:使用 try...except 语句来捕获异常,except 块用于处理捕获到的异常。
  • 异常的传递:当一个异常没有被当前函数捕获时,它会向调用堆栈中上层的函数传递,直到捕获到该异常。
  • 异常链:使用 raise ... from 可以在抛出新异常时保留原始异常信息,帮助跟踪错误发生的根本原因。
  • 抛出异常:使用 raise 可以显式地抛出异常,并且可以在适当的时机传递异常信息给调用方。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DataCrafter

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值