如何恢复pickle类及其实例

时间:2015-12-14 07:02:14

标签: python pickle

我想存储一个类和许多实例供以后使用,或者提供给其他人。

到目前为止,我可以挑选并恢复实例,但我必须在加载之前手动重新创建类。

我查看了this文档,这让我相信我应该能够以某种方式做到这一点,但我似乎无法确切地知道如何做到这一点。

编辑:我已经阅读了answer讨论dill的使用情况(请参阅this回答),但我没有dill安装。如果它存在,我会喜欢泡菜解决方案。

import numpy as np
import pickle

class wow(object):
    def __init__(self, x):
        self.x = x

w5 = wow(np.arange(5))
w3 = wow(range(3))

with open("w5w3.pickle", "w") as outfile:
    pickle.dump([w5, w3], outfile)

# save the class also
with open("wow.pickle", "w") as outfile:
    pickle.dump(wow, outfile)

# OK, now delete class wow, then try to recover the pickles
del wow, w3, w5

try:
    with open("wow.pickle", "r") as infile:
        wow = pickle.load(infile)

except Exception, e:  # returns: "'module' object has no attribute 'wow'"
    print str(e)
    print "so manually recreate class wow"

    class wow(object):
        def __init__(self, x):
            self.x = x  

with open("w5w3.pickle", "r") as infile:
    W = pickle.load(infile)

for thing in W:
    print type(thing.x), thing.x

3 个答案:

答案 0 :(得分:5)

我认为错误是因为您删除了类定义。 Python中的对象序列化(据我所知也是Java)需要类定义。

来自您的链接文档:

  

请注意,函数(内置和用户定义)由“完全限定”的名称引用而非值引用。这意味着只有函数名称被腌制,以及定义函数的模块的名称。函数的代码或其任何函数属性都不会被pickle。因此,定义模块必须可以在unpickling环境中导入,并且模块必须包含命名对象,否则将引发异常。 [4]

     

类似地,类通过命名引用进行pickle,因此适用于unpickling环境中的相同限制。请注意,没有任何类的代码或数据被腌制   

如果您想向朋友发送类和实例,请通过定义类wow的代码和通过pickle文件的实例发送类。

答案 1 :(得分:1)

通常,如果可以挑选该对象的每个属性,则可以挑选任何对象。 无法腌制类,函数和方法

来源:https://wiki.python.org/moin/UsingPickle

不要销毁课程或将其作为模块导入。

答案 2 :(得分:-1)

你必须按照提及here

的二进制模式打开pickle文件
with open('data.pickle', 'wb') as f:
    pickle.dump(data, f)