向JSON文件追加密码数据失败,触发json.decoder.JSONDecodeError错误求助
向JSON文件追加密码数据失败,触发json.decoder.JSONDecodeError错误求助
兄弟我太懂你这种快要崩溃的心情了!你的密码管理器核心功能没问题,但处理JSON文件的逻辑确实踩了好几个坑,这就是为什么第一次能存数据,之后就彻底乱套的原因。咱们一步步把这些坑填上:
你代码里的核心问题:
- 错误的JSON数据检查方式:你用逐行读取JSON文件的方式判断网站是否存在,这完全搞错了JSON的使用逻辑——JSON是结构化的字典数据,不是纯文本,逐行读很容易误判,还会导致文件操作混乱。
json.dump参数顺序搞反:你写的data.dump(data_file, data_dict)完全不对,正确的顺序是json.dump(要写入的数据, 文件对象, 其他参数)。- finally块的致命覆盖:不管前面操作成功与否,finally块都会强制写入
data_dict,直接把之前的所有数据都覆盖了,这就是第一次存完后就坏了的关键原因。 - 重复且混乱的文件IO操作:在try的else分支里重复打开关闭文件,逻辑绕来绕去,很容易出问题。
修正后的add_info函数
def add_info(): website = website_entry.get().strip() email_username = email_username_entry.get().strip() password = password_entry.get().strip() # 先检查所有输入是否为空 if not website or not email_username or not password: messagebox.showerror("ERROR", "Please fill in all fields!") return data_dict = { website: { "email": email_username, "password": password, } } try: # 读取现有JSON数据为字典 with open("data.json", mode="r") as data_file: data = json.load(data_file) # 直接判断网站是否已存在(字典的键查询是最准确的) if website in data: messagebox.showerror("ERROR", "Data for this website already exists.") return # 追加新数据到现有字典 data.update(data_dict) except FileNotFoundError: # 如果文件不存在,直接用新数据初始化 data = data_dict except json.JSONDecodeError: # 处理文件损坏的情况 messagebox.showerror("ERROR", "Existing data file is corrupted, creating new one.") data = data_dict # 统一写入数据到文件(不管是新文件还是追加,只执行一次) with open("data.json", mode="w") as data_file: json.dump(data, data_file, indent=4) # 清空输入框,给用户成功提示 website_entry.delete(0, END) password_entry.delete(0, END) messagebox.showinfo("SUCCESS", "Password saved successfully!")
改进点说明:
- 先做输入校验:避免空数据写入,提升用户体验。
- 正确的JSON数据操作:用
json.load把整个JSON文件加载成Python字典,直接通过键查询判断网站是否存在,这才是JSON的正确打开方式。 - 修复
json.dump参数:把数据和文件对象的顺序改对,保证数据正确写入。 - 移除错误的finally块:把文件写入逻辑统一放在最后,避免强制覆盖数据。
- 增加异常处理:捕获
JSONDecodeError,处理文件损坏的情况,让程序更健壮。
额外小建议:
- 密码生成器可以让用户自定义密码长度,比如加个输入框让用户选8/12/16位,随机性会更灵活。
- 可以给
password_entry加个右键菜单或者按钮,把生成的密码复制到剪贴板,用pyperclip库就能轻松实现。 - 启动程序时可以给
email_username_entry默认填入常用邮箱,比如email_username_entry.insert(0, "your-email@example.com"),减少重复输入。
试一下修改后的代码,应该就能正常追加和保存密码了,祝你顺利搞定这个小项目!
备注:内容来源于stack exchange,提问作者kutari studios
相关产品推荐
相关产品推荐

