08 异常处理
📋 资料说明
- 来源:课程 day08
- 笔记:
尚硅谷大模型技术之Python1.0.docx第 9 章 - 每日一考:
day08_每日一考.md、day08_20251030周四考试.md(含周考题目) - 视频:❌ 跳过(共 11 个视频:异常介绍 → 处理不同类型 → else/finally → raise/assert/with → 自定义异常)
🟢 🤖 AI 替代率:97%
为什么是这个水平:
异常处理语法非常固定:try-except-else-finally 结构和 raise/assert 都是确定性规则。AI 可以准确生成各种异常处理场景的代码。
唯一需要人工判断的是:应该捕获什么异常。捕获太宽(except Exception)会掩盖 bug,捕获太窄(except ValueError)可能漏掉其他异常。但这个判断属于「经验不足 AI 也能设计好"合理"的捕获范围」,影响不大。
👤 人工干预率:3%
几乎无需干预。——了解 try-except-else-finally 的执行顺序和资源清理的 with 语句即可。
1. try-except 基本使用
python
try:
# 可能出错的代码
num = int(input("输入数字: "))
result = 10 / num
print(f"结果是: {result}")
except ValueError:
print("输入的不是数字")
except ZeroDivisionError:
print("不能除以零")捕获多种异常
python
try:
num = int(input("输入数字: "))
result = 10 / num
except (ValueError, ZeroDivisionError) as e:
print(f"出错: {e}")捕获所有异常(不推荐)
python
try:
# 某些操作
pass
except Exception as e:
print(f"发生错误: {e}")
# 不要用裸 except: ——会捕获 KeyboardInterrupt 等系统异常2. else 和 finally
python
try:
num = int(input("输入数字: "))
result = 10 / num
except ValueError:
print("输入的不是数字")
except ZeroDivisionError:
print("不能除以零")
else:
# 没有异常时才执行
print(f"计算成功: {result}")
finally:
# 不管有没有异常都执行
print("程序结束")
# 执行顺序:try → else(无异常时)→ finally
# try → except(有异常时)→ finallyfinally 的典型用途
python
# 资源清理
f = None
try:
f = open("test.txt", "r")
content = f.read()
except FileNotFoundError:
print("文件不存在")
finally:
if f:
f.close() # 确保文件关闭3. raise 抛出异常
python
def withdraw(balance, amount):
if amount <= 0:
raise ValueError("取款金额必须为正数")
if amount > balance:
raise ValueError("余额不足")
return balance - amount
try:
new_balance = withdraw(100, 200)
except ValueError as e:
print(f"取款失败: {e}")自定义异常
python
class InsufficientBalanceError(Exception):
"""余额不足异常"""
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
super().__init__(f"余额 {balance},需要 {amount},差额 {amount - balance}")
def withdraw(balance, amount):
if amount > balance:
raise InsufficientBalanceError(balance, amount)
return balance - amount
try:
withdraw(100, 200)
except InsufficientBalanceError as e:
print(e) # 余额 100,需要 200,差额 1004. assert 断言
python
# assert 条件, "错误信息"
# 条件为 False 时抛出 AssertionError
def divide(a, b):
assert b != 0, "除数不能为零"
return a / b
divide(10, 2) # 5.0
# divide(10, 0) # AssertionError: 除数不能为零assert 与 raise 的区别:
assert:用于开发和调试阶段的"合约检查",可被python -O script.py优化掉raise:用于生产环境的异常处理
5. 异常的传递
python
def func1():
print("func1 开始")
raise ValueError("func1 出错")
def func2():
print("func2 开始")
func1()
print("func2 结束") # 不会执行
try:
func2()
except ValueError as e:
print(f"捕获到: {e}")
# 输出:
# func2 开始
# func1 开始
# 捕获到: func1 出错6. with 语句(上下文管理器)
python
# with 自动管理资源的获取和释放
# 任何实现了 __enter__ 和 __exit__ 方法的对象都可以用 with
# 文件操作(最常用的场景)
with open("test.txt", "w") as f:
f.write("Hello")
# 自定义上下文管理器
class ManagedResource:
def __enter__(self):
print("获取资源")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("释放资源")
return False # 返回 False 表示不屏蔽异常
def do_something(self):
print("使用资源")
with ManagedResource() as res:
res.do_something()
# 输出:
# 获取资源
# 使用资源
# 释放资源练习题
练习 1:输入验证
编写一个函数,接受用户输入的整数,如果输入不是数字则提示重新输入,直到输入正确为止。
练习 2:文件安全读取
读取一个可能不存在的文件,如果不存在则创建并写入默认内容。
练习 3:自定义异常
定义一个 NegativeNumberError 异常类,当计算平方根时传入负数时抛出。
参考答案
练习 1:
python
def get_integer(prompt):
while True:
try:
return int(input(prompt))
except ValueError:
print("请输入一个有效的整数")
num = get_integer("输入数字: ")
print(f"你输入了: {num}")练习 2:
python
def safe_read(filename, default="默认内容"):
try:
with open(filename, "r", encoding="utf-8") as f:
return f.read()
except FileNotFoundError:
with open(filename, "w", encoding="utf-8") as f:
f.write(default)
return default
content = safe_read("config.txt")
print(content)练习 3:
python
class NegativeNumberError(Exception):
pass
import math
def sqrt_positive(n):
if n < 0:
raise NegativeNumberError("不能对负数开平方")
return math.sqrt(n)
try:
print(sqrt_positive(-4))
except NegativeNumberError as e:
print(e)