(十九)菜单拆分、独立练习与下一步
1. 把上一章的菜单按职责拆开
配套的 reading_menu_functions.py 保留上一章的 add、done、list、quit 命令,把它们拆成以下几个函数:
| 函数 | 接收的数据 | 交回的结果或动作 |
|---|---|---|
parse_command(line) |
一行输入 | (命令, 书名或 None) |
add_book(books, title) |
书架字典与书名 | 更新字典,返回提示文字 |
finish_book(books, title) |
书架字典与书名 | 更新已存在记录,返回提示文字 |
format_books(books) |
书架字典 | 返回显示行列表,保留加入顺序 |
main() |
来自 input() 的命令 |
协调检查、调用与输出 |
例如 parse_command("add Python 入门") 返回 ("add", "Python 入门"),parse_command(" ") 返回 ("", None)。解析函数不直接读输入,加入函数不自己打印;因此可以把同样的文本交入解析函数,把同一份字典交入记录函数,逐项核对结果。
仍用上一章的五条命令运行完整文件,输出保持“已加入 Python 入门”“已加入 NumPy”“已标记 Python 入门”、两条清单与“已退出”。再加入空行、缺书名、未知书名与重复加入,检查提示及原有状态。
2. 独立练习
以下任务均为自拟,先写出函数接收什么、返回什么,再实现与核对。
- 最长连续达标天数。 写
longest_streak(values, *, goal=30),接收一次性迭代器也能统计。[35, 40, 0, 45, 50, 60]应返回3,空来源返回0。每读一项,只更新当前连续长度与历史最长长度。 - 菜单增加删除。 为上一节的菜单补
remove_book(books, title),返回提示文字。按“加入 A、完成 A、再次加入 A、删除 A、列清单”执行,重复加入保留已读状态,删除后显示空清单。 - 闭包独立状态。 写一个创建编号器的函数,参数为起始编号。第一份从
1开始,第二份从100开始;交错调用,应得到1、100、2、101,两份状态互不修改。 - 筛选流水线。 把综合示例增加为按闭区间
--min 20 --max 40筛选,输入10 20 35 45后统计两项,总量55、平均27.50。先单独核对生成器交出了哪些值,再核对报告。 - 按书名分组统计。 输入记录
[("A", 20), ("B", 35), ("A", 45)],交回{"A": 65, "B": 35}。分别用普通字典与defaultdict(int)完成,再说明按相邻键分组的groupby会把这份原始顺序分成几段。
3. 本章回查与面向对象的衔接
| 需要的操作 | 查阅主题 |
|---|---|
| 重复一段处理并取得结果 | 函数定义、调用、return 与返回元组 |
| 看清星号与参数名的作用 | 参数收集、拆包、位置与关键字绑定 |
| 解释调用后数据的改变 | 共享对象、重新绑定、可变默认值 |
| 保存一份可以继续更新的状态 | 闭包、nonlocal 与延迟读取 |
| 改变另一段程序的处理动作 | 回调、lambda 与装饰器 |
| 分文件并保留独立入口 | 模块导入、包、__name__ 与 -m |
| 对接口写明数据形状 | 容器注解、联合类型、泛型与 Callable |
| 数据逐项通过多段处理 | 迭代器、生成器、yield from 与 itertools |
| 处理统计、日期、文本和启动参数 | collections、datetime、re、argparse |
现在,书架字典与处理它的函数已经分开。每次增加或完成一本书,都要把同一份字典交给相应函数;若一本书还要保存作者、标签和阅读进度,多份字典的字段与操作也会越来越多。下一章把一条记录的数据与相关操作放在一起,从实际调用出发学习类、实例与对象协作。
本章习题解答与推导 按题号整理实现、过程说明与运行检查,可在完成练习后逐项对照。