Python · Day 23

按编号修改与
永久保存

第二十三天,我为学习记录管理器增加了修改功能。程序会根据用户编号找到指定记录,保存旧内容、替换新内容,再重写文件,让修改在下一次启动后依然存在。

用列表赋值替换指定记录

修改列表元素和普通变量赋值很相似,只是等号左侧变成了列表中的一个位置。用户输入编号 2 时,先减 1 得到索引 1,再替换第二条记录。

day23.py
notes = ["学习函数", "学习文件", "学习菜单"] # 准备三条测试记录
number = 2                                     # 模拟用户选择第 2 条记录
index = number - 1                             # 把显示编号转换成列表索引 1
notes[index] = "复习文件读写"                 # 替换索引 1 保存的旧内容
print(notes)                                   # 查看修改后的完整列表

修改前先保存旧内容

列表赋值会覆盖原位置的内容。如果先修改再读取,旧记录已经消失。因此程序先把 notes[index] 保存到 old_note,再进行替换。

day23.py
old_note = notes[index]                         # 覆盖前先保存原来的记录
notes[index] = new_note                        # 用用户输入的新内容替换旧记录
save_all_notes(notes)                          # 把修改后的列表重写到文件
return "已将“" + old_note + "”修改为“" + new_note + "”" # 返回清楚的修改结果

这样程序能准确显示哪条旧记录被改成了什么新内容,而不是把新内容错误地当成旧内容。

封装完整的修改函数

update_note() 接收记录列表、用户编号和新内容。它负责转换索引、检查范围、修改列表、保存文件并返回结果。

day23.py
def update_note(notes, number, new_note):         # 接收列表、显示编号和新内容
    index = number - 1                           # 把从 1 开始的编号转换成索引

    if index < 0 or index >= len(notes):        # 检查索引是否超出列表范围
        return "修改失败,记录编号不存在"          # 编号无效时立即结束函数

    old_note = notes[index]                      # 保存即将被覆盖的旧内容
    notes[index] = new_note                      # 修改运行期间的列表内容
    save_all_notes(notes)                        # 重写文件,永久保存修改
    return "已将“" + old_note + "”修改为“" + new_note + "”" # 返回修改详情

为什么还要重写文件

notes[index] = new_note 只改变程序运行时的列表。如果不调用 save_all_notes(notes),重新启动程序后还会从硬盘读取旧内容。

永久修改的完整路线是:读取文件 → 得到列表 → 替换列表元素 → 用修改后的完整列表重写文件。

输入新内容之前先检查编号

最初输入不存在的编号 9 时,程序仍会询问新内容,虽然最后不会误改文件,但体验不够自然。改进后,程序先验证用户编号是否在 1 到记录数量之间。

day23.py
if number < 1 or number > len(notes_result):  # 检查用户看到的编号是否有效
    print("修改失败,记录编号不存在")              # 无效编号不再询问新内容
else:                                             # 只有有效编号才继续修改
    new_note = input("请输入新的记录:")           # 接收替换后的新内容
    result = update_note(notes_result, number, new_note) # 修改列表并保存文件
    print(result)                                    # 显示修改成功的详细结果

边界测试输入编号 0 时,程序直接显示“修改失败,记录编号不存在”,没有询问新内容,也没有改变文件中的四条记录。

接入六功能循环菜单

学习记录管理器现在包含添加、查看、搜索、删除、修改和退出六个选项。选择修改功能后会重新读取最新记录,并用 try / except 处理非整数输入。

day23.py
elif choice == "5":                              # 用户选择修改记录功能
    notes_result = load_notes()                        # 修改前读取文件中的最新记录

    if len(notes_result) == 0:                       # 判断当前是否没有记录
        print("暂时没有可以修改的学习记录")          # 空列表时不要求输入编号
    else:                                             # 有记录时继续修改流程
        show_notes(notes_result)                       # 编号显示全部最新记录
        number = int(input("请输入记录编号:"))        # 获取需要修改的显示编号

今天真正掌握的内容

  • notes[index] = new_note 可以替换列表指定位置的内容
  • 用户编号减 1,才能得到从 0 开始的列表索引
  • 修改前要先保存 old_note,否则旧内容会被覆盖
  • 列表修改后必须重写文件,修改结果才能永久保留
  • 用户可见编号的有效范围是 1 到 len(notes)
  • 输入 0、超大编号或非整数时,程序不会误改记录
  • 修改功能已经接入循环菜单,与读取、显示和保存函数协作

删除和修改的共同规律已经很清楚:先读取最新文件得到列表,在内存中完成改变,再把最终列表完整写回文件。