如何使用 pickle 从文件中获取 class 个实例的列表

How to get list of class instances from file using pickle

我有2个类:小组和学生。我创建了不同组的列表,每个组都有 属性 包含学生列表。然后我以这种方式使用 pickle 将其保存在文件中:

tfile = open( 'test', "w" )
pickle.dump(encodedList, tfile)
tfile.close()

这 3 行效果很好。再次启动程序后,我想从列表中的文件中获取所有这些信息,我根据很多这样的教程来做:

encodedList = []
try:
    with open('test') as file:
        tfile = open( 'test', "r" )
        encodedList = pickle.load( tfile )
except IOError:
    tfile = open( 'test', "w" )
    pickle.dump( encodedList, tfile )
tfile.close()

但是 Programm 在这里崩溃并给出下一个错误:

我试图以不同的类似方式从文件中读取这个列表,但这个错误总是一样的,你能帮我吗?

class 定义必须在您解开之前完成:

class foo(): # works
    pass
encodedList = []
try:
    with open('test') as file:
        tfile = open( 'test', "r" )
        encodedList = pickle.load( tfile )
except IOError:
    tfile = open( 'test', "w" )
    pickle.dump( encodedList, tfile )
tfile.close()

失败原因:

encodedList = []
try:
    with open('test') as file:
        tfile = open( 'test', "r" )
        encodedList = pickle.load( tfile )
except IOError:
    tfile = open( 'test', "w" )
    pickle.dump( encodedList, tfile )
tfile.close()


class foo(): # fails
    pass

输出将是 AttributeError: 'module' object has no attribute 'foo',这就是您在自己的代码中看到的。如果 class 定义在另一个文件中,请在尝试 unpickle

之前添加导入

您可以尝试 而不是 使用 pickle,而是使用更好的序列化程序,例如 dill。使用 dill,class 定义与实例的 pickle 一起存储,因此如果您不知道要取消 pickle 的实例类型,这很容易。

>>> class Student(object):
...   def __init__(self, name):
...     self.name = name
...   def __repr__(self):
.. .    return "Student(%s)" % self.name
... 
>>> class Group(list):  
...   pass
... 
>>> myclass = Group([Student('Ted'), Student('Fred'), Student('Jane')])
>>>  
>>> import dill
>>> with open('myclass.pkl', 'w') as f:
...   dill.dump(myclass, f)
... 
>>> 

pickle 实例列表后,退出并开始新会话...

Python 2.7.10 (default, Sep  2 2015, 17:36:25) 
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> with open('myclass.pkl', 'r') as f:
...   myclass = dill.load(f)
... 
>>> myclass
[Student('Ted'), Student('Fred'), Student('Jane')]
>>> [student.name for student in myclass]
['Ted', 'Fred', 'Jane']
>>> type(myclass)
<class '__main__.Group'>

请注意上面的答案实际上是存储一个子class列表的实例,即存储三个class个实例。