【问题标题】:Python Class Inheritance : dict how to pickle(save, load)Python类继承:dict如何腌制(保存,加载)
【发布时间】:2012-11-30 05:44:42
【问题描述】:

我在玩类继承,但我一直纠结于如何在类字典中腌制数据。

如果只转储 self 的字典部分,当我将字典加载回 self 时,self 采用 dict 类型而不是类。但是,如果我腌制整个班级,则会出现错误。

错误

pickle.PicklingError: Can't pickle <class 'main.model'>: it's not the same object as main.model 

代码

import os, pickle

class model(dict):
    def __init__( self ):
        pass

    def add( self, id, val ): 
        self[id] = val

    def delete( self, id ):   
        del self[id]

    def save( self ): 
        print type(self)
        pickle.dump( dict(self), open( "model.dict", "wb" ) )

    def load( self ): 
        print 'Before upacking model.dic, self ==',type(self)
        self = pickle.load( open( "model.dict", "rb" ) ) 
        print 'After upacking model.dic, self ==',type(self)

if __name__ == '__main__':
    model = model()
    #uncomment after first run
    #model.load()

    #comment after first run
    model.add( 'South Park', 'Comedy Central' )
    model.save()

【问题讨论】:

  • 你的代码有什么问题?
  • 我无法重现该错误。你用的是哪个版本的python? save 函数是唯一改变的东西吗?顺便说一句,在load 中,使用self = pickle.load(...) 只会更改名为self 的局部变量,它实际上并不会更改model 对象。
  • 我使用的是 2.7,如果它只是改变 self 那么我需要担心这个吗?
  • 我的意思是 unpickling 实际上并没有做任何事情。 load 方法退出的那一刻,未腌制的统计信息将丢失。 Marwan Alsabbagh 在下面的回答显示了一种更好的方法来酸洗和解开物体。

标签: python class inheritance dictionary pickle


【解决方案1】:

如果您只想拥有一个名为 model 的类,它是 dict 的子类,并且可以正确地腌制和解封回一个也是 model 类型的对象,那么您不必做任何特别的事情。您在示例中定义的添加和删除方法是不必要的,您可以直接在模型实例上执行它们,就像使用任何其他 dict 一样。可以使用 pickle 模块而不是类本身来完成保存和加载方法。

代码

import pickle

class model(dict):
    pass

a = model()
pickled = pickle.dumps(a)
b = pickle.loads(pickled)

print type(a), a
print type(b), b

输出

<class '__main__.model'> {}
<class '__main__.model'> {}

下面是另一个版本,它可能更符合您想要实现的目标。但是您应该以这种方式做事。加载方法很奇怪,保存也很奇怪。我把代码放在下面是为了表明它可以完成,但不是你真正想做的事情,因为它最终会变得非常混乱。

另一个版本(不要这样做)

import pickle

class model(dict):
    def save(self):
        with open("model.dict", "wb") as f:
            pickle.dump(self, f)

    def load(self): 
        with open("model.dict") as f:
            return pickle.load(f)

#comment after first run
test = model()
test['South Park'] = 'Comedy Central'
test.save()
print type(test), test

#uncomment after first run
test2 = model().load()
print type(test2), test2

进一步阅读

可腌制的 dict 子类的一个很好的例子是collections.OrderedDict。它是 python 标准库的一部分,并在 python 中实现,因此您可以在源代码处获得峰值。定义是 172 行代码,所以没有太多的代码可以浏览。它还必须实现__reduce__ 方法来实现酸洗,因为它具有关于也需要酸洗和解酸的项目顺序的信息。这是一个很好的例子,说明了为什么您可能想要创建自己的 dict 子类,它添加了非常有用的特性,即尊重添加到 dict 的值的顺序。

【讨论】:

  • 非常感谢,这有助于解释类继承;也很简单。
  • @Crispy 我用一些可能对你有用的进一步阅读更新了答案。
  • 非常感谢,我一直在寻找这方面的一些资源。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-25
  • 1970-01-01
  • 2011-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多