Learn
Python/07-errors

错误处理

程序出错时不应该直接崩溃。Python 用 try/except 捕获并处理异常。

1. 异常的代价

print(1 / 0)
# ZeroDivisionError: division by zero
ℹ️什么是异常

异常(Exception)是程序运行时的错误事件。它会中断当前执行流,沿调用栈向上抛出,直到被 try/except 捕获或导致程序退出。

2. 基本 try/except

基本捕获
try:
    n = int(input("请输入整数:"))
    print(10 / n)
except ValueError:
    print("这不是一个整数!")
except ZeroDivisionError:
    print("不能除以 0")

3. else 与 finally

  • else:当没有异常时执行
  • finally:无论是否异常都执行(常用于释放资源)
else 与 finally
def safe_div(a, b):
    try:
        r = a / b
    except ZeroDivisionError:
        return None
    else:
        return r          # 没出错才执行
    finally:
        print(f"  safe_div({a},{b}) 调用结束")
 
print(safe_div(10, 2))
print(safe_div(10, 0))

/>

4. 常见异常类型

异常触发场景
ValueError类型对但值不合法,如 int("abc")
TypeError类型错误,如 "1" + 1
ZeroDivisionError除以 0
IndexError序列下标越界
KeyError字典键不存在
FileNotFoundError打开不存在的文件
AttributeError对象无此属性
常见异常
samples = [
    ("int('abc')", lambda: int("abc")),
    ("'1'+1",      lambda: "1" + 1),
    ("[1,2][5]",   lambda: [1, 2][5]),
    ("{}['x']",    lambda: {}["x"]),
]
for name, f in samples:
    try:
        f()
    except Exception as e:
        print(f"{name} -> {type(e).__name__}: {e}")

5. 主动抛异常:raise

raise 主动抛错
def set_age(age):
    if age < 0 or age > 150:
        raise ValueError(f"年龄不合理:{age}")
    print(f"年龄已设置为 {age}")
 
try:
    set_age(200)
except ValueError as e:
    print("捕获:", e)

6. 自定义异常

自定义异常
class InsufficientFundsError(Exception):
    """余额不足异常"""
    def __init__(self, balance, amount):
        super().__init__(f"余额 {balance},尝试取出 {amount}")
        self.balance = balance
        self.amount = amount
 
def withdraw(balance, amount):
    if amount > balance:
        raise InsufficientFundsError(balance, amount)
    return balance - amount
 
try:
    withdraw(100, 200)
except InsufficientFundsError as e:
    print("操作失败:", e)

🎯 练习

健壮的输入解析
# 任务:写一个 safe_int 函数,反复要求用户输入直到给出合法整数
# 捕获 ValueError;用户输入 q 时返回 None 退出
# 期望效果:
#   请输入:> abc
#   无效,请重试
#   请输入:> 42
#   已接收:42
 
def safe_int():
    while True:
        s = input("请输入:")
        if s == "q":
            return None
        # 补全代码
        pass
 
print(safe_int())

小结

  • ✅ try/except 捕获异常;else 无异常时执行;finally 总是执行
  • ✅ 多个 except 按顺序匹配
  • ✅ raise 主动抛异常
  • ✅ 自定义异常继承 Exception
  • ✅ 不要用 except: 吞掉所有异常(会包括 KeyboardInterrupt 等)
  • ✅ 异常信息(e)是宝贵的调试线索

下一章 文件 I/O:读写文件与 JSON。