目标
写一个命令行 todo 工具,支持:
$ python todo.py add "买菜"
✓ 已添加 #1 买菜
$ python todo.py list
[ ] #1 买菜
$ python todo.py done 1
✓ 完成 #1
$ python todo.py list
[x] #1 买菜
数据存到本地 todos.json 文件。
完整代码
# todo.py
import json
import sys
from pathlib import Path
DATA_FILE = Path("todos.json")
class TodoStore:
def __init__(self, file: Path):
self.file = file
self.todos = self._load()
def _load(self):
if not self.file.exists():
return []
try:
return json.loads(self.file.read_text(encoding="utf-8"))
except json.JSONDecodeError:
print("⚠ 数据文件损坏,重置")
return []
def _save(self):
self.file.write_text(
json.dumps(self.todos, ensure_ascii=False, indent=2),
encoding="utf-8",
)
def add(self, text):
next_id = (max((t["id"] for t in self.todos), default=0)) + 1
self.todos.append({"id": next_id, "text": text, "done": False})
self._save()
print(f"✓ 已添加 #{next_id} {text}")
def list(self):
if not self.todos:
print("(暂无 todo)")
return
for t in self.todos:
mark = "x" if t["done"] else " "
print(f"[{mark}] #{t['id']} {t['text']}")
def done(self, tid):
for t in self.todos:
if t["id"] == tid:
t["done"] = True
self._save()
print(f"✓ 完成 #{tid}")
return
print(f"⚠ 找不到 #{tid}")
def main():
store = TodoStore(DATA_FILE)
args = sys.argv[1:]
if not args:
print("用法: python todo.py [add|list|done] ...")
return
cmd = args[0]
if cmd == "add" and len(args) >= 2:
store.add(" ".join(args[1:]))
elif cmd == "list":
store.list()
elif cmd == "done" and len(args) >= 2:
try:
store.done(int(args[1]))
except ValueError:
print("⚠ ID 必须是数字")
else:
print(f"⚠ 未知命令: {cmd}")
if __name__ == "__main__":
main()
用了哪些前面学过的东西
| 知识点 | 出现位置 |
|---|---|
类 + __init__ + self |
TodoStore |
| 默认参数 | default=0 |
| 列表 / 字典 | self.todos |
| 文件读写 | _load / _save |
| 异常处理 | json.JSONDecodeError |
| f-string | print 输出 |
| 模块 import | json / sys / pathlib |
| pathlib | DATA_FILE |
| 命令行参数 | sys.argv |
| 推导式 | max(... default=0) |
if __name__ == "__main__" |
入口 |
试着扩展
- 加
delete <id>命令 - 加
--priority标记 - 加 deadline 日期,list 时按 deadline 排序
- 改用
argparse做更专业的命令行解析
写完这些,你的 Python 基础就过关了。
下一篇:基础课程总结 + 路线图。