Python密码生成器:JSON追加数据报错与SQLite3存储AttributeError问题求助
密码生成器的JSON追加与SQLite存储问题解答
一、初始遇到的JSONDecodeError:空文件无法解析
咱们先拆解第一个问题:当你第一次运行程序时,saved.json要么不存在,要么是空文件,json.load(file)尝试读取空内容时必然报错——因为JSON格式要求必须有有效值(比如数组、对象),空字符串完全不符合规范。
另外你代码里的entry = {password}是个集合,JSON是不支持序列化集合类型的,这也是个隐藏坑,得先改成JSON能处理的类型,比如直接存密码字符串,或者存包含密码的字典(方便后续扩展备注、生成时间等信息)。
修正后的JSON追加代码
我推荐把文件读写分开处理,逻辑更清晰,也能避免r+模式下seek()带来的定位问题:
filename = 'saved.json' # 把集合改成字符串(或字典,按需选择) entry = password # 直接存密码字符串 # 如果想存更多信息,比如生成时间,可以用字典: # entry = {"password": password, "created_time": datetime.datetime.now().isoformat()} # 先读取现有数据,处理文件不存在或为空的情况 try: with open(filename, "r") as file: data = json.load(file) # 确保data是列表(防止之前错误存了单个值) if not isinstance(data, list): data = [data] except (FileNotFoundError, json.JSONDecodeError): # 文件不存在或者解析失败,初始化空列表 data = [] # 追加新密码 data.append(entry) # 写入文件(用w模式直接覆盖,避免残留旧内容) with open(filename, "w") as file: json.dump(data, file, indent=2) # indent=2让JSON格式更美观,方便查看
二、SQLite存储时的AttributeError: 'str' object has no attribute 'values'
这个错误的根源有两个:
- 你之前的
entry是集合,JSON序列化后会导致数据结构混乱,加载后的pwStored不是你预期的格式; - 你写的
tuple(i.values)完全错配了数据类型——如果pwStored是字符串列表,i就是单个密码字符串,字符串根本没有values方法。
修正后的SQLite存储代码
假设你的Passwords表只有一个存储密码的列(建议加上创建表的语句,避免表不存在的报错):
情况1:JSON里存的是字符串列表(对应上面的entry = password)
store = input('Would you like to store the password? ') if store.strip().lower() == "yes": # 加strip和lower让输入更友好,支持"Yes"、"yes"、" YES"等格式 pwStored = json.loads(Path("saved.json").read_text()) with sqlite3.connect("db.pws") as conn: # 先创建表(如果不存在的话) conn.execute(""" CREATE TABLE IF NOT EXISTS Passwords ( id INTEGER PRIMARY KEY AUTOINCREMENT, password TEXT NOT NULL ) """) command = "INSERT INTO Passwords (password) VALUES (?)" # 循环每个密码,直接传入字符串元组 for pwd in pwStored: conn.execute(command, (pwd,)) # 注意元组的逗号不能少,否则会被当成单个字符串而非元组 conn.commit() print("密码已成功存入数据库!") else: print("程序退出。")
情况2:JSON里存的是字典列表(对应entry = {"password": password})
如果用字典存储,取密码的时候要指定对应的键:
# ...前面的代码和上面一致 for item in pwStored: conn.execute(command, (item["password"],)) # ...后面的代码一致
为什么之前的代码会报错?
你写的conn.execute(command, tuple(i.values)),如果i是字符串,字符串没有values()方法,自然会抛出AttributeError;就算i是字典,i.values()返回的是一个视图对象,正确写法是tuple(i.values())(注意括号),但直接取item["password"]会更清晰,不容易出错。
内容的提问来源于stack exchange,提问作者FrocketGaming
相关产品推荐
相关产品推荐

