Pyinstaller 应用无法读取但可以写入文件

Pyinstaller app can't read but can write to files

我做了一个简单的密码存储应用程序,但我只放了可能有问题的代码。当我 运行 来自 python 的这段代码时,它 运行 正是我想要的,但是当我用 pyinstaller 转换它时,它无法按我想要的方式工作。 每次我尝试注册并重新启动程序时,它都希望我一次又一次地注册。 当我在 storage.py 中登录信息并将 registered 变量设置为 True 然后将文件转换为 exe 时它可以工作但是没有注册屏幕,只有登录屏幕。 另外,当我更改登录信息时,它不适用于新的,我仍然必须使用旧的登录。 我假设读取文件存在问题,因为写入工作完美。 我尝试了 --onedir 和 --onefile 两种模式,还使用 ​​--add-data 添加了文件,但仍然没有。

密码Storage.py文件:

from tkinter import *
from tkinter import messagebox
from resources.storage import *

root = Tk()
root.title('Password Storage')
root.iconbitmap('resources/password_storage.ico')

frame1 = LabelFrame(root, padx=10, pady=10)
frame1.grid(row=0, column=0, padx=5, pady=5)

def submit_register():
    if username_register != '' and password_register != '':
        registered = True
        with open('resources/storage.py', 'w') as storage:
            storage.write(f'\nregistered = {registered}\nstorage_username = \'{hashing(username_register.get())}'
                          f'\'\nstorage_password = \'{hashing(password_register.get())}\'')
            storage.write('\n\nstorage = {\n')
            for key, value in passwords.items():
                storage.write(f'\t\'{key}\': {value},\n')
            storage.write('}\n')
        if messagebox.showinfo('Info', 'Successfully saved. Application needs to be restarted.') == 'ok':
            root.quit()
    else:
        messagebox.showerror('Error', 'You didn\'t fill all input fields!')


def submit_login():
    if username_login.get() == storage_username and password_login.get() == storage_password:
        for widget in frame1.winfo_children():
            widget.grid_forget()
    else:
        messagebox.showerror('Error', 'Wrong username or password!')


if not registered:
    for widget in frame1.winfo_children():
        widget.grid_forget()
    Label(frame1, text='Register').grid(row=0, columnspan=2)
    Label(frame1, text='New username: ').grid(row=1, column=0)
    username_register = Entry(frame1, borderwidth=3)
    username_register.grid(row=1, column=1)
    Label(frame1, text='New password: ').grid(row=2, column=0)
    password_register = Entry(frame1, borderwidth=3)
    password_register.grid(row=2, column=1)
    Button(frame1, text='Submit', command=submit_register).grid(row=3, columnspan=2)

elif registered:
    for widget in frame1.winfo_children():
        widget.grid_forget()
    Label(frame1, text='Login').grid(row=0, columnspan=2)
    Label(frame1, text='Username: ').grid(row=1, column=0)
    username_login = Entry(frame1, borderwidth=3)
    username_login.grid(row=1, column=1)
    Label(frame1, text='Password: ').grid(row=2, column=0)
    password_login = Entry(frame1, borderwidth=3)
    password_login.grid(row=2, column=1)
    Button(frame1, text='Submit', command=submit_login).grid(row=3, columnspan=2)

storage.py 文件:

registered = False
storage_username = ''
storage_password = ''

storage = {
}

我按照 BoadGules 的评论中的建议使这个程序与 pickle 模块一起工作。非常感谢!

“您的程序将密码作为 Python 源代码存储在 storage.py 中。当您 运行 pyinstaller 时,它会将源代码转换为字节码,然后字节码是包装到 .exe 中的内容。您的程序可能对 storage.py 的源代码所做的任何后续更改都不会影响 .exe 的行为方式:您的代码保持在原始状态版本。这就是它的工作原理。如果你想使用 pyinstaller 然后将数据存储为 Python 源不是一个好的解决方案。看看 pickle 模块,这是最喜欢你在做什么,或者 configparser."