错误处理
程序出错时不应该直接崩溃。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:无论是否异常都执行(常用于释放资源)
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
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。