多个对象在pickle文件中

3 投票
3 回答
702 浏览
提问于 2025-04-18 10:24

我想把多个对象保存到一个pickle文件里,并且以后能把它们取出来。现在我已经能保存对象了,但当我加载文件的时候,只能加载到最后一个对象。我哪里出错了呢?

import pickle

class People():
    def __init__(self, name, surname, age, mobile_no, home_no):
        self.name = name
        self.surname = surname
        self.age = age
        self.mobile_no = mobile_no
        self.home_no = home_no

    def DisplayContacts(self):
        print("First Name: \t", self.name)
        print("Surname: \t", self.surname)
        print("Age: \t", self.age)
        print("Mobile Number: \t", self.mobile_no)
        print("Home Number: \t", self.home_no)
        print()


def addContact():
    newname = str(input("First name: \t"))
    newsurname = str(input("Surname: \t"))
    newage = int(input("Age: \t"))
    newmobile_no = int(input("Mobile Number: \t"))
    newhome_no = int(input("Home Number: \t"))
    newContact = People(newname, newsurname, newage, newmobile_no, newhome_no) 
    return newContact

cont = 1

contacts = []


while cont == 1:
    user = input("Do you want to add contact? (Y/N)")
    if user == "Y" or user == "y":
        print ("works")
        contacts.append(addContact())
        file = open("List.pickle", "wb")
        pickle.dump(contacts, file, pickle.HIGHEST_PROTOCOL)
        file.close()
    else:
        print ("111")
        cont = 0

useropen = input("open file? (Y/N)")
if useropen == "Y" or useropen == "y":
    with open ("List.pickle", "rb") as pickled_file:
        contacts = pickle.load(pickled_file)
else:
    print("Null")

现在看起来,当我尝试加载文件时,它是空的:

import pickle

class People():
    def __init__(self, name, surname, age, mobile_no, home_no):
        self.name = name
        self.surname = surname
        self.age = age
        self.mobile_no = mobile_no
        self.home_no = home_no

    def DisplayContacts(self):
        print("First Name: \t", self.name)
        print("Surname: \t", self.surname)
        print("Age: \t", self.age)
        print("Mobile Number: \t", self.mobile_no)
        print("Home Number: \t", self.home_no)
        print()


def addContact():
    newname = str(input("First name: \t"))
    newsurname = str(input("Surname: \t"))
    newage = int(input("Age: \t"))
    newmobile_no = int(input("Mobile Number: \t"))
    newhome_no = int(input("Home Number: \t"))
    newContact = People(newname, newsurname, newage, newmobile_no, newhome_no) 
    return newContact

cont = 1

contacts = []


while cont == 1:
    user = input("Do you want to add contact? (Y/N)")
    if user == "Y" or user == "y":
        print ("works")
        contacts.append(addContact())
        file = open("CList.pickle", "ab")
        pickle.dump(contacts, file, pickle.HIGHEST_PROTOCOL)
        file.close()
    else:
        print ("111")
        cont = 0

useropen = input("open file? (Y/N)")
if useropen == "Y" or useropen == "y":

    with open ("CList.pickle", "rb") as pickled_file:
        contacts = pickle.load(pickled_file)
else:
    print("Null")

3 个回答

2

补充一下@Ethan Furman说的内容,'b'在Windows和Unix系统中的功能似乎有些不同(参考链接)。你的代码在Unix系统上可能运行得很好,但在Windows操作系统上可能会出现截断的问题。

4

你在每次循环的时候都在重新写你的Pickle文件,因为你是用"wb"模式打开它的。

在这个循环中,你一直在往contacts列表里添加联系人(然后每次循环都把这个列表的一个新副本保存下来——这可能不是你想要的效果)。我建议你把保存Pickle文件的那部分代码移到while循环之后,只保存一次完整的联系人列表,这样就不需要保存多个对象了。

4

你现在用 wb 模式打开你的 pickle 文件,这个模式会把文件清空,然后再写入新的内容。你其实应该用 a 模式,这个模式是用来在文件末尾添加内容的。

撰写回答