如何在 python 中准确保存程序状态?

How to EXACTLY save the state of a program in python?

我正在制作一个小型 gui 应用程序,它从文本文件中提取单词并转换为 python 列表,显示它,提供 yes/no 按钮,单击后显示下一个随机单词并删除之前的单词显示该列表中的单词。问题是,如果我想关闭应用程序,我如何确保在单击几下后它知道我离开的地方并在下次我再次打开它时从那里开始,而不是回到没有任何文字的原始状态从列表中删除。换句话说,我如何准确地保存我的 运行 程序的当前状态以便我以后可以恢复它?

我四处搜索并找到了有关序列化的信息,PickleJSON 确实如此,但它们对我来说并没有真正的意义,我也不明白如何在这里实现它们。

代码:

from random import randint
from tkinter import *

dictionary=[]
with open('Dictionary.txt', 'r') as words:
    dictionary = [word.split('\n')[0] for word in words]


root= Tk()
root.title('')
root.geometry('300x500')

#progress = 0

def yes_():
    #select a random number
    n = randint(0,len(dictionary))
    
    #pass to list and print word on label
    global l
    l.grid_forget()
    l = Label(root, text = dictionary[n])
    l.config(font=('Arial', 25))
    l.grid(row=0, padx=100, pady=100)

    #remove that word
    dictionary.remove(dictionary[n])
    #progress += 1

def no_():
    global l
    l.grid_forget()
    l = Label(root, text='test click')
    l.config(font=('Arial', 25))
    l.grid(row=0, padx=100, pady=100)

l = Label(root, text='Hello')
l.config(font=('Arial', 30))
l.grid(row=0, padx=100, pady=100)


question = Label(root, text='Do you know this word?', anchor='center')
question.config(font=('Arial', 12))
question.grid(row=1, pady=20)

by = Button(root, text='Yes', command=yes_)
by.config(font=('Arial', 15))
by.grid(row=2, ipadx=20)

bn = Button(root, text='No', command=no_)
bn.config(font=('Arial', 15))
bn.grid(row=3, pady=10, ipadx=26)

root.mainloop()

编辑1:
好的,所以在@fernandezr 和@Cool 的建议之后,我做了一些搜索,我能够将更改的列表 dictionary 保存到 pickle 中。 (我没听懂 @acw1668 和 @Tkinter 在说什么,抱歉,伙计们)但是现在我如何让它加载回来,这样当我再次打开程序时它会从那里恢复?

码位:

def on_close():
    with open(r'C:\Users\Tos\Documents\t.pickle', 'wb') as text:
        pickle.dump(dictionary, text)
    root.destroy()

...

root.protocol('WM_DELETE_WINDOW', on_close)
root.mainloop()

好的,所以针对我的具体情况,我找到了解决方案。在我的问题中,我做了一个编辑,我找到了如何保存程序,确切地说,我能够制作一个有效的保存机制。对于加载机制,我只需要加载保存的文件(如@acw1668 所建议的那样)并将其分配给变量 dictionary,这会将由 .txt 文件生成的原始列表替换为更改后的列表来自 pickled 文件。

整个代码:

from random import randint
from tkinter import *
import pickle

dictionary=[]
with open('Dictionary.txt', 'r') as words:
    dictionary = [word.split('\n')[0] for word in words]

root= Tk()
root.title('')
root.geometry('300x500')

def on_close():
    with open(r'C:\Users\Tos\Documents\t.pickle', 'wb') as t_pickle:
        pickle.dump(dictionary, t_pickle)
    root.destroy()

def yes_():
    n = randint(0,len(dictionary))
    global text_label
    text_label.grid_forget()
    text_label = Label(root, text = dictionary[n])
    text_label.config(font=('Arial', 25))
    text_label.grid(row=0, padx=100, pady=100)
    dictionary.remove(dictionary[n])

def no_():
    global text_label
    text_label.grid_forget()
    text_label = Label(root, text='test click')
    text_label.config(font=('Arial', 25))
    text_label.grid(row=0, padx=100, pady=100)

try:
    with open(r'C:\Users\Tos\Documents\t.pickle', 'rb') as t_pickle:
        dictionary = pickle.load(t_pickle)
except FileNotFoundError:
    pass

text_label = Label(root, text='Hello')
text_label.config(font=('Arial', 30))
text_label.grid(row=0, padx=100, pady=100)

question = Label(root, text='Do you know this word?', anchor='center')
question.config(font=('Arial', 12))
question.grid(row=1, pady=20)

by = Button(root, text='Yes', command=yes_)
by.config(font=('Arial', 15))
by.grid(row=2, ipadx=20)

bn = Button(root, text='No', command=no_)
bn.config(font=('Arial', 15))
bn.grid(row=3, pady=10, ipadx=26)

root.protocol('WM_DELETE_WINDOW', on_close)
root.mainloop()

如果你想知道我为什么使用 try..except 块,那么原因是用户第一次打开程序时没有任何可用的保存文件,所以让错误很容易通过。这也适用于在创建文件时保存程序的部分,因此可以继续进行。

最后我想说的是,虽然我得到了我想要的,但我觉得这是一个变通办法。我期待 python 有一些功能或实现 save/load 功能的东西;也许是这样,但我不知道,我不是 python 方面的专家。可能我对问题的措辞不正确。我仍然有兴趣知道如何 pause/save 运行 程序的状态,我发现许多 stackeroverflow 用户问同样的事情但没有得到预期的答案。如果有人确实知道 python 中的 运行 程序存在 save/load/暂停功能,请执行 link 它。