agentmentoragentmentor

第 08 节:把零件合成一个小 CLI

本节 objectives:

  • 设计一个最小命令行待办工具的数据流
  • 组合函数、列表和文件读写完成 add/list/done
  • 用最小异常处理让输入错误不直接炸掉程序

先修:前 7 节全部内容 | 上一节 << 07 | 下一节 README >>

项目不是多写语法,而是让零件排成一条线

一个小 CLI 的核心流程很短:读入文件里的任务,根据用户命令修改列表,再把列表写回文件。控制流、函数、列表和文件都已经学过;现在只是把它们接起来。

这节会出现一点异常处理。Python 文档把异常描述为会打断正常流程的错误,可以用 try 语句处理1。这里我们只处理一个场景:用户输入的编号不是合法数字。

讲解

先定命令,再写代码。 本项目只支持三件事:add 买牛奶 添加任务,list 显示任务,done 2 标记第二条任务完成。范围小,程序才容易完成。

文件格式保持简单。 每行一条任务,完成状态用前缀保存:0|read docs 表示未完成,1|read docs 表示完成。这样读取时能拆成字典,写回时能还原成文本。

函数按数据流拆。 load_tasks() 负责文件到列表,save_tasks() 负责列表到文件,show_tasks() 负责显示,命令分支负责修改。

错误先温和处理。 done two 这种输入不能转成整数,会产生异常;项目里用 try/except ValueError 给出提示,不让程序直接显示大段堆栈1

跟我做一遍(worked example)

先写核心函数:

python
PATH = "tasks.txt"
def load_tasks():    tasks = []    try:        with open(PATH, "r", encoding="utf-8") as f:            for line in f:                done_text, title = line.strip().split("|", 1)                tasks.append({"title": title, "done": done_text == "1"})    except FileNotFoundError:        return []    return tasks
def save_tasks(tasks):    with open(PATH, "w", encoding="utf-8") as f:        for task in tasks:            done_text = "1" if task["done"] else "0"            f.write(done_text + "|" + task["title"] + "\n")

这里先接受一个现实:第一次运行时文件可能不存在。所以 load_tasks() 遇到 FileNotFoundError 就返回空列表。保存时总是把当前列表完整写回文件。

换你补全(faded example)

补全显示函数,让完成项显示 [x],未完成项显示 [ ]:

python
def show_tasks(tasks):    number = 1    for task in tasks:        if task["done"]:            mark = ____        else:            mark = ____        print(f"{number}. [{mark}] {task['title']}")        number = number + 1

答案:

python
def show_tasks(tasks):    number = 1    for task in tasks:        if task["done"]:            mark = "x"        else:            mark = " "        print(f"{number}. [{mark}] {task['title']}")        number = number + 1

关键判断点是:显示格式不改变原数据,它只是把布尔值转成人能看的标记。

小结 + 通向下一节

你已经完成了第一条编程闭环:运行脚本、表达状态、做选择、重复处理、封装函数、组织数据、保存文件、组合成一个小工具。后续学 Python 时,不要先追语法大全;继续拿小项目逼自己回答同一个问题:数据从哪里来,变成什么形状,最后到哪里去。

Footnotes

  1. Python Tutorial: Errors and Exceptions — https://docs.python.org/3/tutorial/errors.html 2

练习

Level 1: 完成 addlist

  • 做法:写一个脚本,先手动设置 command = "add"title = "read docs",把任务加入列表并保存;再改成 command = "list" 显示文件里的任务。
提示 1

先别处理真实命令行参数,用变量模拟命令。 Level 2: 完成 done 并处理坏输入。

  • 做法:设置 index_text = "1",把对应任务的 done 改成 True;再试 index_text = "abc"
提示 2

try: index = int(index_text) - 1 包住转换。 Level 3: 常见错误剖析。

  • 做法:故意删除 save_tasks(tasks),运行 add 后再运行 list。
提示 3

每次修改数据后问一句:要不要写回文件?

看参考答案

变量只活在一次运行里,文件才是跨运行的记忆。

自评