user2415010
user2415010

Reputation:

Why is Pickle not serializing my array of classes?

I'm trying to serialize a large number of custom classes to disk using python's pickle. However, the classes aren't serializing properly.

Having looked at the docs it's my understanding what I'm trying to do ought to work, but perhaps it's not simply because I'm not understanding something.

My classes are defined at the top-level of the module. And no PicklingError exception is being fired when trying to pickle.

Here is my sample code. Uncomment Save() to serialize; uncomment Load() to load. When loading, the Synonyms array of Term isn't being populated, but the Main object of Term is being deserialized. You can see this by inspecting the "loadedTerms" object being returned from the Load() function.

What am I doing wrong? Thanks.

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()

Upvotes: 0

Views: 2466

Answers (1)

Daniel
Daniel

Reputation: 42758

Pickle only saves the instance attributes of a class, but Synonyms is a list, defined at class level. You should create the list in a __init__-method:

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

Upvotes: 3

Related Questions