练手小项目,不依赖第三方库,单文件,存 JSON。熟悉 argparse / 文件 IO / 数据建模刚好。
完整源码
#!/usr/bin/env python3
"""todo.py —— 极简命令行待办"""
import argparse, json, os
from dataclasses import dataclass, asdict
DATA = os.path.expanduser('~/.todo.json')
@dataclass
class Item:
id: int
text: str
done: bool = False
def load():
if not os.path.exists(DATA):
return []
with open(DATA, encoding='utf-8') as f:
return [Item(**d) for d in json.load(f)]
def save(items):
with open(DATA, 'w', encoding='utf-8') as f:
json.dump([asdict(i) for i in items], f, ensure_ascii=False, indent=2)
def cmd_add(args):
items = load()
nxt = max((i.id for i in items), default=0) + 1
items.append(Item(nxt, args.text))
save(items)
print(f'已添加 #{nxt} {args.text}')
def cmd_list(args):
for i in load():
if args.all or not i.done:
mark = 'x' if i.done else ' '
print(f'[{mark}] {i.id:>3} {i.text}')
def cmd_done(args):
items = load()
for i in items:
if i.id == args.id:
i.done = True
save(items)
print(f'#{args.id} 已完成')
def cmd_rm(args):
items = load()
save([i for i in items if i.id != args.id])
print(f'已删除 #{args.id}')
def main():
p = argparse.ArgumentParser(prog='todo')
sub = p.add_subparsers(dest='cmd', required=True)
a = sub.add_parser('add'); a.add_argument('text'); a.set_defaults(func=cmd_add)
l = sub.add_parser('list'); l.add_argument('-a','--all',action='store_true'); l.set_defaults(func=cmd_list)
d = sub.add_parser('done'); d.add_argument('id', type=int); d.set_defaults(func=cmd_done)
r = sub.add_parser('rm'); r.add_argument('id', type=int); r.set_defaults(func=cmd_rm)
args = p.parse_args()
args.func(args)
if __name__ == '__main__':
main()
用法
几个可以自己加的功能
- 加
-p/--priority优先级字段,list 时排序 - 加
due截止日期,过期标红(用 ANSI 转义) - 换成 SQLite 存储,支持多设备同步
- 加
edit子命令改内容
这类小工具最大的价值是把「重复的手工步骤」固化下来。我自己用的版本加了
todo add -t 2h记录预估工时,月底一统计就知道时间花哪了。
楼主 · 2026-09-28 13:21 · 浏览 0

