python 用 collections.counter 按类别汇总支出最省事,但需确保类别字段为非空字符串;双重汇总宜用 pandas groupby;预算报警应分滚动周期与单笔阈值两层;sublime 插件中 json 读写须指定 utf-8 编码并原子替换;分类名称须通过别名映射和录入约束统一,时间字段强制 iso 格式。

支出分类汇总用 Python 的 collections.Counter 最省事
直接对支出记录按类别字段计数,比手写字典累加更少出错,也天然支持后续排序和筛选。注意类别字段必须是字符串类型,如果原始数据里是 None 或数字(比如分类 ID),得先统一转成可哈希的字符串,否则 Counter 会抛 TypeError: unhashable type。
实操建议:
- 读取 CSV 或 JSON 数据后,用
[row.get("category", "未知").strip() for row in data]提前清洗,避免空格或缺失导致分类错乱 - 若需按月+类别双重汇总,别硬套
Counter,改用pandas.DataFrame.groupby(["month", "category"])["amount"].sum()更稳 - Sublime 中调试时,在 Python 构建系统输出里看到
Counter({'餐饮': 420, '交通': 185})就说明归类成功,不用额外 print 每一项
预算超支报警逻辑不能只比“本月总支出 > 预算”
真实场景中,用户可能当月刚录入大额历史补录支出,或预算本身是按周/双周设置的。硬性阈值触发会误报。建议把报警拆成两层:基础层用滚动 30 天支出对比当月预算,增强层加一个“单笔超预算 30%”的即时标记。
实操建议:
- 存储预算值时,不要只存一个全局
monthly_budget = 5000,而是用字典如{"2024-06": 5000, "2024-07": 4800},方便动态调整 - 报警触发后,用
sublime.status_message("⚠️ 餐饮超支:¥1280/¥800")直接推到 Sublime 状态栏,比弹窗干扰小 - 避免在每次保存文件时实时计算——Sublime 的
on_post_save事件里做全量扫描太慢,应改为仅检查刚修改的行是否属于超支类别
Sublime 插件里读写 JSON 资产数据要处理编码和原子性
Windows 上默认用 GBK 写入 JSON,Linux/macOS 默认 UTF-8,跨平台打开会报 UnicodeDecodeError: 'gbk' codec can't decode byte。另外,直接 f.write(json.dumps(...)) 可能写到一半崩溃,导致数据损坏。
实操建议:
- 始终显式指定
encoding="utf-8":用json.dump(data, f, ensure_ascii=False, indent=2)写,json.load(f, encoding="utf-8")读 - 写入前先写到临时文件(如
assets.json.tmp),写完再os.replace()原子替换,防止中断损坏主文件 - 在插件的
plugin_loaded()里加一次校验:尝试json.load()主文件,失败则自动从最近的.bak文件恢复,并用sublime.error_message()提示用户
分类名称不一致是汇总失真的最大隐形杀手
用户手动录入时,“外卖”“外送”“美团外卖”“饿了么”常被当成不同类别,但业务上都属于“外卖餐饮”。靠后期正则模糊匹配成本高、易误伤。必须在录入端就约束。
实操建议:
- 在 Sublime 的自定义语法或命令中,给支出行添加 Tab 补全:输入
wa按 Tab 自动展开为外卖餐饮,而不是让用户自由打字 - 维护一个映射表
CATEGORY_ALIAS = {"waimai": "外卖餐饮", "sd": "水电费", "gz": "工资"},录入时优先查别名再落库 - 定期跑校验脚本:用
set(all_categories) - set(allowed_categories)找出非常规分类,标黄显示并建议合并——这个动作可以做成右键菜单命令,叫“检查分类规范性”
Sublime 不是数据库,所有汇总和报警都依赖本地文件结构稳定。最常被忽略的是时间字段格式:"2024/06/15"、"2024-06-15"、"15-Jun-2024" 混用会让日期分组直接失效。统一用 ISO 格式 "2024-06-15" 并在保存前强制校验,比后期修复强十倍。











