You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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'

这个错误的根源有两个:

  1. 你之前的entry是集合,JSON序列化后会导致数据结构混乱,加载后的pwStored不是你预期的格式;
  2. 你写的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 18:57:31