Irazall
Irazall

Reputation: 157

Why does a pickle loaded after saving differs from the original object?

I use pickle in order to save a list of objects. After saving the list with pickle and loading this very same list again I compare the newly loaded list with the original list. Strangely those two objects differ. Why is this the case? Shouldn't it be the same?

I already tried to use only instance attributes that are defined in the init-function and no class attributes but the error remains.

import pickle as p

class Person(object):
    def __init__(self, name=None, job=None, quote=None):
        self.name = name
        self.job = job
        self.quote = quote


personList = [Person("Payne N. Diaz", "coach", "Without exception, there is no rule!"),
              Person("Mia Serts", "bicyclist", "If the world didn't suck, we'd all fall off!"),
              Person("Don B. Sanosi", "teacher", "Work real hard while you wait and good things will come to you!")]

with open('test_list.p', 'wb') as handle:
    p.dump(personList, handle, protocol=p.HIGHEST_PROTOCOL)

with open('test_list.p', 'rb') as handle:
    personList2 = p.load(handle)

print(personList == personList2)

I expect that True will be printed out but the result printed is False.

Upvotes: 9

Views: 564

Answers (2)

jdpy19
jdpy19

Reputation: 375

Running your code and printing personList1 and personList2; it appears that you are checking if the objects are the same, not if the contents are the same.

False
[<__main__.Person object at 0x000001A8EAA264A8>, <__main__.Person object at 0x000001A8EAA26A20>, <__main__.Person object at 0x000001A8EAA26F98>]
[<__main__.Person object at 0x000001A8EAA26240>, <__main__.Person object at 0x000001A8EAA260F0>, <__main__.Person object at 0x000001A8EAA26908>]

Where if you change your print statement to the following, it will yield true because it is checking the contents.

print(personList[0].name == personList2[0].name)

Upvotes: 1

Daniel Roseman
Daniel Roseman

Reputation: 599610

You haven't defined an explicit way to compare Person objects. Therefore, the only way Python can compare them is by their IDs (ie their memory address). The address of the items you've loaded from the pickle will be different from the originals - as they must be, because they are new objects - so the lists will not compare equal.

You can declare an explicit __eq__ method on the Person class:

class Person(object):
    def __init__(self, name=None, job=None, quote=None):
        self.name = name
        self.job = job
        self.quote = quote

    def __eq__(self, other):
        return (self.name == other.name and self.job == other.job and self.quote == other.quote)

Now your comparison will return True as expected.

Upvotes: 8

Related Questions