Python 入门实战:从零写一个命令行待办清单工具

举报
yd_217917957 发表于 2026/10/28 06:02:10 2026/10/28
【摘要】 很多新手学完 Python 语法,却不知道第一个能真正用起来的程序该写什么。待办清单是一个很好的起点:它足够小,可以在一个文件里完成;又足够真实,涉及输入、存储、查询和修改,几乎覆盖了日常编程最常用的思路。本文就用标准库完成一个命令行待办清单,不依赖第三方包,也不需要数据库。 先想清楚:程序要解决什么问题在写代码之前,先把需求写成一句话:用户可以在命令行添加任务、查看任务、标记完成和删除任务...

很多新手学完 Python 语法,却不知道第一个能真正用起来的程序该写什么。待办清单是一个很好的起点:它足够小,可以在一个文件里完成;又足够真实,涉及输入、存储、查询和修改,几乎覆盖了日常编程最常用的思路。本文就用标准库完成一个命令行待办清单,不依赖第三方包,也不需要数据库。

先想清楚:程序要解决什么问题

在写代码之前,先把需求写成一句话:用户可以在命令行添加任务、查看任务、标记完成和删除任务,关闭程序后数据仍然存在。这句话里已经藏着三个设计要点。第一,任务需要一个唯一标识,否则删除和完成时容易改错行。第二,任务至少要有内容和完成状态两个字段。第三,数据要落盘保存,否则每次启动都会丢失。

用字典和列表表示任务

最直观的做法,是用一个字典表示一条任务,用列表保存全部任务。例如每条任务包含编号、内容和是否完成。编号可以按已有任务的最大值加一生成,避免重复。列表的好处是顺序自然,打印时也方便编号。初学者常常一开始就想设计很复杂的类,其实先把数据结构想简单,程序反而更容易写对。

用 JSON 文件做持久化

保存数据不需要先学数据库,Python 标准库里的 json 模块就够了。程序启动时先读取一个 JSON 文件,如果文件不存在,就从空列表开始;退出或每次修改后,再把列表写回文件。这样做还有一个好处:数据文件是纯文本,出了问题可以直接打开查看。需要注意的是,写入时要处理好中文编码,读取时要对文件损坏的情况做基本容错,不要让一次异常就把全部数据弄丢。

命令行入口要简单直观

命令可以设计得很直接:add 后面跟任务内容,list 查看全部任务,done 后面跟编号表示完成,delete 后面跟编号表示删除。实现时可以用 sys.argv 读取参数,也可以用 argparse 生成更友好的帮助信息。对新手来说,先用 sys.argv 理解参数就是字符串列表,再过渡到 argparse 会更自然。每个命令对应一个小函数,主函数只负责分发,这样以后加新命令时改动也很小。

演示与自测

写完后可以按顺序做一次完整演练:添加三条任务,查看列表,标记其中一条完成,再删除一条,最后重新启动程序确认剩余任务还在。如果某一步结果不对,先打印任务列表和文件内容,确认是命令解析错了,还是数据保存错了。把问题定位到一层,比反复改代码更有效。

新手最容易踩的三个坑

第一是编号和列表下标混淆。用户看到的编号从一开始,而列表下标从零开始,转换时要小心。第二是忘记保存。只改了内存里的列表,没有写回文件,下次启动就会以为程序丢了数据。第三是把所有逻辑都写进一个大函数里,导致调试困难。按添加、查看、完成、删除和保存拆成小函数,是很好的练习。

可以继续扩展的方向

完成基础版后,可以再加三个小功能:按完成状态筛选、给任务加截止日期、支持简单的关键词搜索。这些扩展都不需要换技术栈,却能让你练习条件判断、日期处理和字符串匹配。等你对这个小工具足够熟悉,再去学习面向对象、单元测试或图形界面,都会有更具体的落脚点。

import json
import sys

FILE = "todos.json"

def load():
    try:
        with open(FILE, encoding="utf-8") as f:
            return json.load(f)
    except FileNotFoundError:
        return []

def save(todos):
    with open(FILE, "w", encoding="utf-8") as f:
        json.dump(todos, f, ensure_ascii=False, indent=2)

def main():
    todos = load()
    if len(sys.argv) < 2:
        print("用法:python todo.py add/list/done/delete")
        return
    cmd = sys.argv[1]
    if cmd == "add" and len(sys.argv) > 2:
        new_id = max([t["id"] for t in todos], default=0) + 1
        todos.append({"id": new_id, "text": sys.argv[2], "done": False})
        save(todos)
    elif cmd == "list":
        for t in todos:
            mark = "完成" if t["done"] else "待办"
            print(t["id"], mark, t["text"])

总结一下:先想清楚数据,再写读写逻辑,最后把命令拆成小函数。一个能每天用起来的小工具,比十个只跑过一次的示例更有价值。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。