【问题标题】:Why can't pickle a list that is an attribute of an object?为什么不能腌制作为对象属性的列表?
【发布时间】:2013-08-21 15:32:49
【问题描述】:

我正在尝试腌制一个自定义类的实例,这个类有一个名为“widgets”的属性,其中包含一个小部件对象列表。当我腌制容器时,列表丢失了。不能在对象中腌制列表吗?

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,结果相同。

【问题讨论】:

  • 我无法重现此问题 - 使用您的代码,使用 python 2.7.5,print container.widgets 打印 [<__main__.Widget object at 0x1004c2350>]。您能否尝试运行上面的代码,看看是否有同样的问题?也许您未显示的代码中的某些内容导致了问题。
  • 可以重现 python 2.7.5 的问题。
  • Brionius,这几乎是确切的代码,它包含在一个文件中,我注释/取消注释酸洗和解酸。如果我一次运行它并在同一个脚本中腌制/取消腌制,它确实有效,但我不确定为什么会这样。

标签: python python-2.7 pickle


【解决方案1】:

widgetsclass Container 的属性,而不是 Container 类的 instance 的属性。当您腌制实例时,您并没有腌制类属性,而只是腌制了实例属性。所以当你解开它时,你只会得到实例属性。

您应该阅读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()

【讨论】:

  • 感谢文档的链接,我正在学习 python,我跳过了看起来像我在其他语言中期望的那样工作的部分,但我不断发现 python 的工作方式不同。
【解决方案2】:

绝对可以在 Python 中腌制 List 对象。您正在使用的自定义类可能覆盖了__getstate____setstate__ 方法,其中开发人员决定不通过从要腌制/取消的属性集中删除小部件列表来腌制小部件列表为该课程腌制。

请参阅here 了解更多信息。如果您可以观察这个自定义类的源代码并检查是否确实如此,那就太好了

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-03
      • 1970-01-01
      • 2010-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-11
      相关资源
      最近更新 更多