为什么不能挑选作为对象属性的列表?

时间:2013-08-21 15:32:50

标签: python python-2.7 pickle

我试图挑选一个自定义类的实例,这个类有一个名为“widgets”的属性,它包含一个widget对象列表。当我腌制我的容器时,列表就丢失了。是不是可以在对象中挑选一个列表?

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

后来我试图破解......

# 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 []

我尝试过pickle和cPickle,效果相同。

3 个答案:

答案 0 :(得分:5)

widgets Container的一个属性,而不是Container类的实例的属性。当你腌制实例时,你没有腌制类属性,只有实例属性。因此,当你取消它时,你只会得到实例属性。

您应该阅读python docs

中的实例与类属性

如果你想挑选小部件,那么你应该使列表成为实例属性而不是类属性。这是一个例子:

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

答案 1 :(得分:0)

绝对可以在Python中挑选List对象。您正在使用的自定义类可能已经覆盖了__getstate____setstate__方法,其中开发人员决定不通过从属性集中删除它来挑选小部件列表那个级别的腌制/非腌制。

有关详细信息,请参阅here。如果您可以观察此自定义类的源代码并检查是否确实如此

,那将是一件好事

答案 2 :(得分:0)

问题是小部件是一个类属性,并没有被腌制。如果您在同一会话中进行unpickle,该脚本似乎可以工作,因为Container.widgets已经是您想要的。当你开始一个新的会话时它不起作用,因为没有填充Container.widgets。