【问题标题】:Why is Pickle not serializing my array of classes?为什么 Pickle 不序列化我的类数组?
【发布时间】:2017-05-24 18:31:02
【问题描述】:

我正在尝试使用 python 的 pickle 将大量自定义类序列化到磁盘。但是,这些类没有正确序列化。

看过docs 之后,我明白我正在尝试做的事情应该有效,但也许这不仅仅是因为我不理解某些东西。

我的类是在模块的顶层定义的。尝试腌制时不会触发 PicklingError 异常。

这是我的示例代码。取消注释 Save() 以进行序列化;取消注释 Load() 以加载。加载时,不会填充 Term 的 Synonyms 数组,但正在反序列化 Term 的 Main 对象。您可以通过检查从 Load() 函数返回的“loadedTerms”对象来看到这一点。

我做错了什么?谢谢。

import pickle

class Entry:
    Text = ""

    def __init__(self, text):
       self.Text = text

class Term:

    Main = None
    Synonyms = []


def Save():
    term = Term()
    term.Main = Entry("Dog")
    term.Synonyms.append(Entry("Canine"))
    term.Synonyms.append(Entry("Pursue"))
    term.Synonyms.append(Entry("Follow"))
    term.Synonyms.append(Entry("Plague"))

    terms = []
    terms.append(term)

    with open('output.pickle', 'wb') as p:
        pickle.dump(terms, p)

def Load():
    loadedTerms = []

    with open('output.pickle', 'rb') as p:
        loadedTerms = pickle.load(p)

    return loadedTerms


#Save()
#terms = Load()

【问题讨论】:

  • 类按名称腌制。酸洗一个类不会保存它的状态,解酸它不会尝试生成一个新的类副本或恢复酸洗时类的状态。
  • 很确定你的类定义没有做你认为他们正在做的事情。但据我所知,您的 Synonyms 属性 is 正在填充​​span>
  • 我还是一头雾水。我为密集而道歉。那么腌制一个物体有什么好处呢?为什么它腌制“主要”对象(我可以很好地反序列化它),而不是数组“同义词”的元素。文档说,“请注意,没有任何类的代码或数据被腌制,因此在以下示例中,类属性 attr 不会在 unpickling 环境中恢复:”但随后它转身说,“同样,当类实例被腌制,他们的类的代码和数据不会一起腌制。只有实例数据被腌制。”
  • @juanpa.arrivillaga 你能解释一下吗?我很想学习。
  • 是的。虽然这不是 python 术语,但是是的。而您在Text.__init__ 中实际所做的是:self.Text = text遮蔽 静态变量 Textinstance 变量 text。所以你有一个无用的静态变量...

标签: python python-3.x pickle


【解决方案1】:

Pickle 只保存类的实例属性,但Synonyms 是一个列表,在类级别定义。您应该在__init__-方法中创建列表:

import pickle

class Entry:
    def __init__(self, text):
       self.Text = text

class Term:
    def __init__(self):
        self.Main = None
        self.Synonyms = []

def Save():
    term = Term()
    term.Main = Entry("Dog")
    term.Synonyms.append(Entry("Canine"))
    term.Synonyms.append(Entry("Pursue"))
    term.Synonyms.append(Entry("Follow"))
    term.Synonyms.append(Entry("Plague"))

    terms = []
    terms.append(term)

    with open('output.pickle', 'wb') as p:
        pickle.dump(terms, p)

def Load():
    with open('output.pickle', 'rb') as p:
        loadedTerms = pickle.load(p)
    return loadedTerms

【讨论】:

  • 非常感谢您的回复,这是有道理的。最后一个问题:您说“同义词”是一个列表,在班级级别定义。但是在我的示例中,Main 是否也没有在类级别定义?
  • 你将Save第二行中的Main重新定义为实例属性。
  • 啊哈!所以我 使用 同义词 - 这是在类级别声明的 - 因为我通过 .append() 调用明确地引用它......但我通过将其设置为等于某物来重新定义 Main。好的。正如你所知道的,我对 python 仍然很熟悉。我的背景是 C 语言世界。感谢您抽出宝贵时间以如此翔实的方式回答我的问题。
  • 所以当您执行term.Main = Entry("Dog") 时,您在instance 命名空间隐藏“静态”主目录,创建实例变量Name。现在静态 Main 无法从实例中访问,因为它将始终使用它的实例变量 Main
  • 非常感谢!
猜你喜欢
  • 2012-02-16
  • 1970-01-01
  • 2013-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-31
  • 1970-01-01
相关资源
最近更新 更多