Reputation: 1035
I am trying to pickle an instance of a custom class, this class has an attribute called "widgets" that contains a list of widget object. When I pickle my container the list is lost. Is it not possible to pickle a list within an object?
import pickle
filename = 'container.pkl'
class Container(object):
widgets = []
class Widget(object):
pass
c = Container()
c.name = "My Container"
w = Widget()
w.name = "My Widget"
c.widgets.append(w)
data = open(filename, 'wb')
pickle.dump(c, data)
data.close()
Later I try to unpickle...
# assume I have imported the classes and filename here
data = open(filename, 'rb')
container = pickle.load(data)
data.close()
print container.name # shows the pickled name
print container.widgets # shows []
I have tried pickle and cPickle with the same results.
Upvotes: 2
Views: 4476
Reputation: 46626
widgets
is an attribute of the class Container
not an attribute of the instance of the Container
class. When you pickled the instance you haven't pickled the class attributes, just the instance attributes. So when you unpickle it you get just the instance attributes back.
You should read about instance vs. class attributes in the python docs
If you want to pickle the widgets too, then you should make the list an instance attribute instead of a class attribute. Here is an example:
import pickle
filename = 'container.pkl'
class Container(object):
def __init__(self, name):
self.name = name
self.widgets = []
class Widget(object):
def __init__(self, name):
self.name = name
c = Container('My Container')
w = Widget('My Widget')
c.widgets.append(w)
data = open(filename, 'wb')
pickle.dump(c, data)
data.close()
Upvotes: 8
Reputation: 77387
The problem is that widgets is a class attribute and wasn't pickled. The script will appear to work if you unpickle in the same session because Container.widgets is already what you want. It will not work when you start a new session because the Container.widgets will not have been populated.
Upvotes: 0
Reputation: 4767
It is definitely possible to pickle List objects within Python. It is possible that the custom class you are using may have overridden the __getstate__
and __setstate__
methods, where-in the developer has decided not to pickle the widget list by deleting it from the set of attributes to be pickled/un-pickled for that class.
Refer here for more information. It would be good if you can observe the source code for this custom class and check if this indeed the case
Upvotes: 0