ToDoList控制台应用如何实现多对象序列化且不重写tasks.json文件
ToDoList-Console多对象序列化实现方案
前置说明
你给出的示例JSON存在语法错误:数组元素之间缺少逗号、ComplexTask的子任务结构不合法、重复的subtask键,无法直接被标准JSON解析器读取,建议先调整为合法的存储格式。
实现方案推荐
因为你要求新增任务时无需重写整个文件,更推荐使用JSON Lines存储格式(每行存储一个独立的合法JSON对象),天然支持增量追加写入,性能和稳定性都远高于修改整段JSON数组的方案。
核心逻辑
- 序列化:给
SimpleTask和ComplexTask统一实现序列化方法,输出带type标识字段的单条JSON字符串,新增任务时直接以追加模式写入文件末尾即可,无需读取原有内容。 - 反序列化:按行读取文件内容,每行单独解析JSON,根据
type字段判断实例化对应类的对象,汇总后返回任务列表。
代码示例(Python)
任务类定义
import json from dataclasses import dataclass, field from typing import List, Union @dataclass class SimpleTask: content: str # 固定类型标识,用于反序列化判断 type: str = field(init=False, default="SimpleTask") def serialize(self) -> str: return json.dumps(self.__dict__, ensure_ascii=False) @classmethod def deserialize(cls, data: dict) -> "SimpleTask": return cls(content=data["content"]) @dataclass class ComplexTask: content: str subtasks: List[str] # 固定类型标识,用于反序列化判断 type: str = field(init=False, default="ComplexTask") def serialize(self) -> str: return json.dumps(self.__dict__, ensure_ascii=False) @classmethod def deserialize(cls, data: dict) -> "ComplexTask": return cls(content=data["content"], subtasks=data["subtasks"])
读写方法实现
def append_task(task: Union[SimpleTask, ComplexTask], file_path: str = "tasks.json"): """新增任务,仅追加写入,不修改原有文件内容""" with open(file_path, "a", encoding="utf-8") as f: f.write(task.serialize() + "\n") def load_all_tasks(file_path: str = "tasks.json") -> List[Union[SimpleTask, ComplexTask]]: """反序列化读取所有任务""" tasks = [] with open(file_path, "r", encoding="utf-8") as f: for line in f: line = line.strip() if not line: continue data = json.loads(line) if data["type"] == "SimpleTask": tasks.append(SimpleTask.deserialize(data)) elif data["type"] == "ComplexTask": tasks.append(ComplexTask.deserialize(data)) return tasks
存储效果示例
{"type": "SimpleTask", "content": "do the dishes"} {"type": "ComplexTask", "content": "buy groceries", "subtasks": ["bananas", "apples"]} {"type": "SimpleTask", "content": "do some coding"}
强制使用JSON数组格式的兼容方案
如果你一定要用你给出的数组格式存储,可通过移动文件指针实现追加:
- 首次创建文件时写入左中括号
[和右中括号] - 每次新增任务时,将文件指针移动到倒数第一个字符(右中括号的位置)
- 如果不是第一个任务,先写入逗号分隔,再写入新任务的JSON内容,最后补写右中括号
]
该方案稳定性差,操作不当容易损坏原有文件内容,仅作为备选。
内容的提问来源于stack exchange,提问作者Rarowcun
相关产品推荐
相关产品推荐

