user1904898
user1904898

Reputation: 79

Python Pickle not saving entire object

I'm trying to pickle out a list of objects where the objects contain a list. When I open the pickled file I can see any data in my objects except from the list. I'm putting code below so this makes more sense.

Object that contains a list.

class TestPickle:
    testNumber = None
    testList = []

    def addNumber(self, value):
        self.testNumber = value
    def getNumber(self):
        return self.testNumber

    def addTestList(self, value):
        self.testList.append(value)
    def getTestList(self):
        return self.testList

This example I create a list of the above object (I'm adding one object to keep it brief)

testPKL = TestPickle()
testList = []
testPKL.addNumber(12)
testPKL.addTestList(1)
testPKL.addTestList(2)
testList.append(testPKL)

with open(os.path.join(os.path.curdir, 'test.pkl'), 'wb') as f:
    pickle.dump(testList, f)

Here is an example of me opening the pickled file and trying to access the data, I can only retrieve the testNumber from above, the testList returns a empty list.

pklResult = None
with open(os.path.join(os.path.curdir, 'test.pkl'), 'rb') as f:
    pklResult = pickle.load(f)

for result in pklResult:
    print result.getNumber() # returns 12
    print result.testNumber  # returns 12
    print result.getTestList() # returns []
    print result.testList      # returns []

I think i'm missing something obvious here but I'm not having any luck spotting it. Thanks for any guidance.

Upvotes: 2

Views: 2268

Answers (1)

AlokThakur
AlokThakur

Reputation: 3741

testNumber and testList both are class attributes initially. testNumber is of immutable type hence modifying it create new instance attribute, But testList is of mutable type and can be modified in place. Hence modifying testList doesn't create new instance attribute and it remains as class attribute. You can verify it -

print testPKL.__dict__
{'testNumber': 12}
print result.__dict__
{'testNumber': 12}

So when you access result.testList, it looks for class attribute TestPickle.testList, which is [] in your case.

Solution

You are storing instance in pickle so use instance attribute. Modify TestPickle class as below -

class TestPickle:
    def __init__(self):
        self.testNumber = None
        self.testList = []

    def addNumber(self, value):
        self.testNumber = value
    def getNumber(self):
        return self.testNumber

    def addTestList(self, value):
        self.testList.append(value)
    def getTestList(self):
        return self.testList

Upvotes: 3

Related Questions