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

Python密码管理器报decrypted变量未定义错误修复

问题原因

报错核心是两个层面的问题:

  • 变量作用域错误:decrypted是你写在add()函数嵌套的logic()函数里的局部变量,和saved()函数不在同一个作用域,saved()根本访问不到这个变量。而且就算你加了全局声明,只要用户没点过保存按钮触发logic()执行,decrypted就从来没被赋值过,点查看密码的时候必然报未定义错误。
  • 加密逻辑本身有严重bug:每次保存密码都会重新生成新的加密密钥,之前存的所有密码会永久无法解密;解密完成后你反而把加密后的乱码写回了明文密码文件,后续读写全是错的。
修复方案
  1. 调整密钥初始化逻辑,密钥只在第一次运行程序时生成,不要每次存密码都替换密钥,把这段代码放到全局初始化位置(也就是window=customtkinter.CTk()这行下面):
    KEY_PATH = "MyKey.key"
    ENC_FILE_PATH = "enc_passwords.txt"
    # 密钥不存在才生成
    if not os.path.exists(KEY_PATH):
        init_key = Fernet.generate_key()
        with open(KEY_PATH, "wb") as key_file:
            key_file.write(init_key)
    # 全局加载加密器
    with open(KEY_PATH, "rb") as key_file:
        crypto_key = key_file.read()
    fernet = Fernet(crypto_key)
    
  2. 重写logic()里的加密存储逻辑,删掉错误的明文写入、重复生成密钥的代码,改成追加新条目后统一加密存储:
    def logic():
        # 非空校验
        if platform_.get() == "" or user.get() == "" or password.get() == "":
            mb.showerror("WRONG INPUT","Please Make sure to enter all the fields \nIf you don't have a username/password Enter 'None'")
            return
        # 拼接新的密码条目
        new_entry = f"Platform: {platform_.get()} | Username/Email: {user.get()} | Password: {password.get()}\n"
        # 读取已有加密内容,解密后追加新条目
        exist_content = b""
        if os.path.exists(ENC_FILE_PATH):
            with open(ENC_FILE_PATH, "rb") as enc_file:
                exist_content = fernet.decrypt(enc_file.read())
        exist_content += new_entry.encode("utf-8")
        # 重新加密写回文件
        encrypted = fernet.encrypt(exist_content)
        with open(ENC_FILE_PATH, "wb") as enc_file:
            enc_file.write(encrypted)
        # 清空输入框
        platform_.delete(0, END)
        user.delete(0, END)
        password.delete(0, END)
        mb.showinfo("Success", "Password saved")
    
  3. 重写saved()函数,不要访问不存在的局部变量,直接读取加密文件现场解密,同时修正多窗口的写法:
    def saved():
        if not os.path.exists(ENC_FILE_PATH):
            mb.showinfo("Tip", "No saved passwords yet")
            return
        # 读文件解密
        with open(ENC_FILE_PATH, "rb") as enc_file:
            decrypted_content = fernet.decrypt(enc_file.read()).decode("utf-8")
        # 子窗口用Toplevel不要新建CTk主窗口,避免事件循环冲突
        new_window = customtkinter.CTkToplevel(window)
        new_window.title("Saved Passwords")
        new_window.geometry("650x400")
        saved_passwords = customtkinter.CTkLabel(new_window, text=decrypted_content, justify="left")
        saved_passwords.pack(padx=20, pady=20, fill="both", expand=True)
    
  4. 删掉原代码里把加密内容写回pass.txt的错误代码,不要留存明文密码文件,所有密码统一存在加密后的enc_passwords.txt里,避免明文泄露。
额外优化提示
  • 你在各个嵌套函数里反复调用main_func()会重复生成侧边按钮组件,造成内存泄漏,只需要在页面切换时保留侧边按钮就可以,不需要每次重绘。
  • 原代码里写的global encrypted没有实际作用,Python中函数内给变量赋值时,需要在函数内部声明global才会关联全局变量,修复后不需要全局变量存储加解密内容,随用随读文件更安全。

内容的提问来源于stack exchange,提问作者user19164169

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:39:30