双体软件精英产业学院 第31期 实操项目1博客:充电器管理系统
作者:赵彬宏 · 炽阳二部(AI二部)Book思议组 完成时间:2026.9.29 — 2026.9.30 发布平台:GitHub
一、项目是什么
项目1是双体的第一个实操项目,要求把前面学过的知识串起来做一个完整的小系统。我做的是一个命令行充电器管理系统——数据不是瞎编的,直接来自我自己的数码图鉴网站 chargers.js,一共 28 款真实充电器,每条记录保留四个字段:产品名、价格、总功率、接口数量。
{"产品名": "酷态科10号SE 超级电能充", "价格": 108, "总功率": 120, "接口数量": 3}
全部用 Python 标准库完成,不装任何第三方库就能跑(语音朗读除外,那个是可选的)。
二、功能一览
主菜单 9 个功能 + 1 个详情二级菜单:
| 编号 | 功能 | 说明 |
|---|---|---|
| 1 | 查看所有充电器 | 列出全部记录,输入序号可进入详情操作 |
| 2 | 添加充电器 | 完全同名时会询问是否仍要添加 |
| 3 | 删除充电器 | 名称模糊匹配,多个匹配时选序号 |
| 4 | 修改充电器 | 直接回车保留原值 |
| 5 | 查询充电器 | 名称关键词 / 价格区间 / 功率区间 / 接口数量 |
| 6 | 保存到文件 | 写入 JSON,并自动备份旧数据 |
| 7 | 重新加载文件 | 丢弃内存修改,从文件重新读取 |
| 8 | 排序查看 | 价格升/降序、功率降序、接口数量降序,不动原顺序 |
| 9 | 数据统计 | 总数、平均价格/功率、最贵/最便宜、功率最高、接口分布 |
在”查看所有充电器”里输入序号,还能进详情二级菜单,对选中的充电器连续操作:修改、删除(要输 y 确认)、语音朗读参数、一键打开京东搜索页比价。
三、项目结构:代码第一次真正”分了家”
这周刚学完模块,项目里就直接用上了。整个项目拆成 5 个文件:
main.py 程序入口:菜单循环、功能分发、退出时自动保存
operations.py 业务功能:显示/添加/删除/修改/查询/排序/统计/详情菜单
storage.py 数据存取:JSON 读写、备份、加载校验
tts.py 语音朗读:pyttsx3 封装,没装依赖就提示跳过
test_project.py 简单测试:22 个检查点,python test_project.py 直接跑
拆的时候有个刻意的设计:operations.py 内部又分了两层——
- 纯逻辑函数:
find_indexes、filter_by_range、compute_stats、sort_chargers这些,不碰 input/print,给数据返回结果; - 交互函数:负责输入输出,内部调用纯逻辑函数。
这么拆的好处是测试代码可以直接调用纯逻辑函数验证结果,不用模拟键盘输入。test_project.py 里 22 个检查点大部分测的就是这一层。
四、用到的知识点(前面学的全用上了)
这个项目最爽的地方就是把前几周零散学的东西全串起来了:
- 列表套字典:28 条记录就是一个列表,每条是字典——第三周练的 movies、models 那套结构直接搬过来;
- 函数封装:每个功能一个函数,菜单只负责分发——第四周练的
def、return、参数默认值全用上了; - 打擂台找最值 + 字典计数:
compute_stats()里找最贵/最便宜/功率最高用的就是打擂台,接口数量分布用的就是d[k] = d.get(k, 0) + 1那个套路(虽然我这里用的是 if 判断版本); - 文件读写 + json 模块:
with open()读写 JSON 文件,json.dump(chargers, f, ensure_ascii=False, indent=2)——ensure_ascii=False是为了让中文正常显示,不然全变成\uXXXX; - try/except 异常处理:
read_int()里循环加try: int(text),输错了提示重输,程序不会崩;Ctrl+C中断也会自动保存再退出; - import 模块拆分:
from storage import load_chargers, save_chargers这种导入方式,刚学完就用; sorted(key=lambda ...)排序:这个比课程进度超前一点,key=lambda c: c["价格"]表示”按每条记录的价格字段来比大小”。
另外还顺手用了几个课外的库:urllib.parse.quote 把中文产品名转成网址编码拼京东搜索链接、webbrowser 打开浏览器、pyttsx3 语音合成。
五、开发中踩的坑
-
删除、修改都要先”找到那一条”,代码重复严重:一开始删除、修改、详情三处各写了一遍”关键词查找→列出匹配→选序号”,越写越烦。后来抽成
choose_charger()一个函数,三处调用,清爽多了——这就是第四周博客里说”把重复逻辑抽成函数”的手感,这次算真正练到了。 -
数据安全比想象中麻烦:刚开始保存就是直接
json.dump覆盖写,后来想——万一写到一半程序崩了,或者 JSON 文件被改坏了怎么办?于是加了一套防护:每次保存前先把旧文件备份成.bak;加载时逐条校验字段和类型,格式不对的记录跳过并提示;主文件损坏时自动从.bak恢复。测试里也专门写了”把主文件改成乱码再加载”的用例验证这条路。 -
输入校验是个体力活:用户可能输字母、输空、输超出范围的序号、区间上下限输反……每种都得兜住。最后统一封装了
read_int()(循环读到整数为止)、read_nonempty()(读到非空为止)、read_range()(两个数反了自动交换),后面所有功能复用这三个,不用每个地方都写一遍 try/except。 -
“能跑通”和”扛造”是两回事:功能写完第一遍跑得很顺,但拿测试一怼——空列表、重复名字、损坏文件、非法输入——各种问题才暴露出来。这次专门写了
test_project.py,用临时文件测存储层(不碰真实数据),22 个检查点全过才算完。
六、总结
项目1做完最大的感受:单个知识点都不难,难的是把它们组织成一个不崩的系统。以前练习是”一道题一个坑”,现在是几十处输入、一个数据文件、五个模块互相调用,任何一处没兜住都会连环出问题。
其次就是模块化真的香—— main.py 只有 60 行,干干净净;想加新功能就往 operations.py 里加函数、菜单里加一行分支,其他地方完全不用动。
下一步如果继续完善,想试试把接口数量从”手填数字”改成按接口配置自动折算(比如 2C1A 自动算 3 个),还有统计那块可以加个按品牌分组。先把欠下的练习补完再说。
本博客为「双体学习笔记」系列,欢迎在评论区交流指正。
本文同步自 Study-Note · 查看原文 ↗