如何使用Python从.pkl文件中解析对象

2024-04-26 12:09:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了一个学生类。我将每个学生的详细信息存储在一个文件中详细信息问题是在取消拾取它给第一个对象的数据时只有。可以有人说如何检索.pkl文件中的所有对象吗

我的代码是

这是我的密码

'''
Created on Apr 20, 2015

@author: murali

'''
import pickle
from pip._vendor.distlib.compat import raw_input
class Student:
    def __init__(self, name, roll, sex, subject, total):
        """Return a new Car object."""
        self.name = name
        self.roll = roll
        self.sex = sex
        self.subject = subject
        self.total = total

print ("*************MENU*******************************")
print ("\t 1.Add New Student")
print ("\t 2.Display all Students")
print ("\t 3.Delete Student")
print ("\t 4.Display all Boys")
print ("\t 5.Display all Girls")
print ("\t 6.Display ascending order of marks")
print ("\t 7.Display alphabetical order of names ")
print ("\t 0.exit")
print ("************************************************")

print ("\n Enter your choice")
ch=int(raw_input())

if ch==1:
    print ("Enter Student Details")     
    print ("Enter Student Name")  
    n=raw_input()
    print ("Enter Student Roll number") 
    r=raw_input()
    print ("Male or Female")
    s=raw_input()
    print ("Enter Subject ")
    su=raw_input()
    print ("Enter Student marks ")
    t=raw_input()
    s=Student(n,r,s,su,t);
    with open("save2.pkl",'ab') as outfile:
        pickle.dump(s,outfile)
        print ("Data saved Successfully")
elif ch==2:
    st=[];
    f=open("save2.pkl",'rb')
    storedlist=pickle.load(f)
    print (storedlist)
    #st.append(storedlist)
    print ("Students are-")
    print (storedlist)
    #for i in storedlist:
    print(storedlist.name)
    print(storedlist.roll)
    print(storedlist.sex)
    print(storedlist.subject)
    print(storedlist.total)
    f.close();
    #s1=None
    #with open("save2.pkl",'rb') as infile:
        #s1=pickle.load(infile)
        #print (s1.name)
        #print (s1.roll)
        #print (s1.sex)
        #print (s1.subject)

Tags: nameselfinputrawdisplaystudentpicklesubject
1条回答
网友
1楼 · 发布于 2024-04-26 12:09:13

您遇到的问题是pickle.load只从pkl文件中读取一个项目。这就是它的设计。如果在同一个文件中有多个项,则需要反复加载它们,直到没有其他内容可读取时得到EOFError。比如:

students = []
try:
    with open("save2.pkl",'rb') as f:
        while True:                          # loop indefinitely
            students.append(pickle.load(f))  # add each item from the file to a list
except EOFError:                             # the exception is used to break the loop
    pass                                     # we don't need to do anything special

或者,您可以在内存中维护您的文件要包含的项目的完整列表(例如,所有Student实例)。当列表被修改时,您将对整个列表进行pickle处理,并在一次调用pickle.dump中将其全部写出,覆盖数据文件中以前的内容。与其在用户请求时读取数据,不如在程序开始时读取数据,如果用户以后需要的话,可以将其保存在内存中。在

这有点难以显示,因为我不想重写大量代码。我想这些片段就是你所需要的:

就在学生阶级的定义之下:

^{pr2}$

当前附加到文件的位置:

s=Student(n,r,s,su,t)
students.append(s)                        # update the in-memory list of students
with open("save2.pkl",'wb') as outfile:   # use mode "w" to overwrite existing file
    pickle.dump(students, outfile)        # dump the whole list, not only s
    print ("Data saved Successfully")

在后面的代码中,您不需要重新读取该文件。它可以使用内存中已有的students列表。在

第二种方法并不是非常有用,因为你当前的菜单设计只能通过一次。但是,如果以后将菜单放入循环中(正如0选项所建议的那样),您可能不需要反复读取数据文件。在

如果您扩展了Student类型以引用其他Student实例(也许您正在为某个团队项目记录实验室合作伙伴或团队),则此方法也比其他版本好得多。如果您分别pickle这些互连对象,当您再次加载它们时,它们之间的链接将不会保留。加载的版本仍将有引用,但引用将指向其他Student实例的副本,而不是其他Student自身加载时得到的相同副本。但是,如果您一次转储并加载一个完整的Student列表,那么它们之间的互连将得到维护。(这是相当深奥的东西,如果你不明白我在说什么,不要太担心。)

相关问题 更多 >