遇到“重新酸洗”的问题

时间:2014-01-16 15:41:21

标签: python pickle

我正在尝试在python中创建联系人应用程序。它相对简单,我认为不需要太多解释。我尝试使用pickle模块来存储元组列表,元组列表是存储实际联系信息的主要格式。程序启动时,会从pickle中保存的位置导入列表phonelist。我设置它来处理错误,因为这是第一次在机器上运行程序并且之前从未在所述机器上腌制过phonelist。我对泡菜知之甚少。这是我第一次使用它。我遇到的这个问题是,在第一次运行程序并首次点击列表后,我无法对列表进行更改。每次我运行程序时,更改列表,关闭程序 - 期望通过在程序结束时发生的列表的腌制来保存我的更改 - 并重新打开它,我获得与非常相同的列表我第一次腌制清单。

    from tkinter import *
    import pickle
    try:
        phonelist = pickle.load( open( "save.p", "rb" ) )
    except FileNotFoundError:
        print ("First Run Error")
        phonelist = [['name', 'phone no.', 'email']]
        pass

    def whichSelected () :
        return int(select.curselection()[0])

    def addEntry () :
        phonelist.append ([nameVar.get(), phoneVar.get(), emailVar.get()])
        setSelect ()

    def updateEntry() :
        phonelist[whichSelected()] = [nameVar.get(), phoneVar.get(), emailVar.get()]
        setSelect ()

    def deleteEntry() :
        del phonelist[whichSelected()]
        setSelect ()

    def loadEntry  () :
        name, phone, email = phonelist[whichSelected()]
        nameVar.set(name)
        phoneVar.set(phone)
        emailVar.set(email)

    def makeWindow () :
        global nameVar, phoneVar, emailVar, select
        win = Tk()

        frame1 = Frame(win)
        frame1.pack()

        Label(frame1, text="Name").grid(row=0, column=0, sticky=W)
        nameVar = StringVar()
        name = Entry(frame1, textvariable=nameVar)
        name.grid(row=0, column=1, sticky=W)

        Label(frame1, text="Phone").grid(row=1, column=0, sticky=W)
        phoneVar= StringVar()
        phone= Entry(frame1, textvariable=phoneVar)
        phone.grid(row=1, column=1, sticky=W)

        Label(frame1, text="Email").grid(row=2, column=0, sticky=W)
        emailVar= StringVar()
        email= Entry(frame1, textvariable=emailVar)
        email.grid(row=2, column=1, sticky=W)

        frame2 = Frame(win)       # Row of buttons
        frame2.pack()
        b1 = Button(frame2,text=" Add  ",command=addEntry)
        b2 = Button(frame2,text="Update",command=updateEntry)
        b3 = Button(frame2,text="Delete",command=deleteEntry)
        b4 = Button(frame2,text=" Load ",command=loadEntry)
        b1.pack(side=LEFT); b2.pack(side=LEFT)
        b3.pack(side=LEFT); b4.pack(side=LEFT)

        frame3 = Frame(win)       # select of names
        frame3.pack()
        scroll = Scrollbar(frame3, orient=VERTICAL)
        select = Listbox(frame3, yscrollcommand=scroll.set, height=6)
        scroll.config (command=select.yview)
        scroll.pack(side=RIGHT, fill=Y)
        select.pack(side=LEFT,  fill=BOTH, expand=1)
        return win

    def setSelect () :
        phonelist.sort()
        select.delete(0,END)
        for name,phone,email in phonelist :
            select.insert (END, name)

    pickle.dump( phonelist, open( "save.p", "wb" ) )

    win = makeWindow()
    setSelect ()
    win.mainloop()

2 个答案:

答案 0 :(得分:0)

在我看来,在运行程序之前,您正在保存电话列表。您应该将保存步骤移至mainloop()退出后。如果要更新mainloop()中的列表,则需要在更新后保存。您可能希望更加直接,在addEntry()updateEntry()deleteEntry()结束时保存,以便您存储的数据不会与内存中的数据不同步如果程序不规则地退出。

答案 1 :(得分:0)

您的代码尝试将任何现有的"save.p"文件读入phonelist。如果由于文件不存在而失败,则会初始化phonelist。但是,在进入应用程序的主循环之前,它会将phonelist中的数据写入文件中(并且在我可以告诉的情况下再也不会)。这意味着该文件永远不会包含初始化数据以外的任何内容,这些数据将被反复读入和写出。

如果应用程序退出时,您需要添加某种保存命令和/或仅(重新)写入文件中的内容。