功能一样、样子天差地别的两段代码,差距在哪?本周学会审查 AI 代码的五类常见问题、 用 assert 写最轻量的测试,再把单文件巨石拆成专业的项目结构——工程化收官。
| 时间 | 环节 | 要点 |
|---|---|---|
| 0–8 | 开场对比 | 两段功能相同的代码:干净版 vs AI 暴力堆砌版——好在哪? |
| 8–22 | 五类常见问题 | 命名不一致/超纲语法/边界缺失/异常粗暴/过度工程化——逐类反面教材 |
| 22–34 | 现场审查重构 | 「能跑但糟」的代码逐步修:密钥/命名/边界/全局变量/零测试 |
| 34–44 | 审查三步法 | 密钥→名字职责→边界;过完三问再运行 |
| 44–58 | 动手练习 | 运行场:可变默认参数陷阱 + assert 三连测试 |
| 58–70 | 模块化 | 300 行巨石的三大问题;按职责拆分;厨房类比 |
| 70–82 | 配置分离 | .env + python-dotenv + config.py;密钥进 .env、代码只读 |
| 82–92 | M4 收官 | 虚拟环境+质量+结构=工程化基本功;下半学期预告 |
| 92–100 | 小测 | 随堂小测 3 题 |
审查三步法在期末项目里每天都要用,从今天开始养成习惯。
except Exception 吞掉所有错误,bug 更难找# AI 初稿:功能是对的,问题你来找
api_key = "sk-abc123" # 问题①:密钥硬编码!
def process(d): # 问题②:process 是什么?d 是什么?
return d.split() # 问题③:d 为空串/None 时崩
results = [] # 问题④:全局变量,多函数共用
# ...零测试... # 问题⑤:没法验证对错
os.getenv() · 函数改名 count_words(text: str) -> dict ·
空输入返回 {} · 结果收进函数返回 · 补 assert count_words("a a b") == {"a":2,"b":1}
测试思维:不是证明代码对,而是尽早发现代码错——正常输入 + 边界输入各测一条。
300 行的 main.py——你愿意接手维护吗?
my_ai_app/
├── .env # API Key(不进仓库)
├── .gitignore
├── requirements.txt
└── app/
├── config.py # 读环境变量
├── client.py # LLM 调用封装
├── stats.py # 数据处理
└── main.py # 入口
# .env(已被 .gitignore 排除)
DEEPSEEK_KEY=sk-xxxxxxxx
# config.py —— 密钥进 .env,配置集中管理
import os
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("DEEPSEEK_KEY") # 读不到就是 None,不会泄露
MODEL = "deepseek-chat"
MAX_TOKENS = 2048
深入阅读:M4 模块页 · 经典笔记 10.2 包管理 · 9.3 包