Python类继承:dict如何pickle(保存,加载)

Cri*_*spy 1 python inheritance dictionary class pickle

我正在玩类继承,我一直在研究如何在类字典中腌制数据.

如果只转换self的字典部分,当我将字典加载回self时,self会使用dict类型而不是类.但如果我挑选整个班级,那我就会收到错误.

错误

pickle.PicklingError: Can't pickle <class 'main.model'>: it's not the same object as main.model 
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

Mar*_*agh 5

如果你想要做的是有一类称为模型是字典的一个子类,可以适合封装和拆封回到一个对象,它是类型的模型还那么你没有做什么特别的.您在示例中定义的添加和删除方法是不必要的,您可以直接在模型实例上执行这些方法,就像使用任何其他dict一样.save和load方法可以使用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
Run Code Online (Sandbox Code Playgroud)

产量

<class '__main__.model'> {}
<class '__main__.model'> {}
Run Code Online (Sandbox Code Playgroud)

下面是另一个版本,可能更符合你想要达到的目标.但是,你应该不是这样做事.加载方法很奇怪,因此保存.我把下面的代码表明它可以完成,但不是你想要做的事情,因为它最终会让你感到困惑.

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

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
Run Code Online (Sandbox Code Playgroud)

进一步阅读

可选择的dict子类的一个很好的例子是collections.OrderedDict.它是python标准库的一部分,并在python中实现,因此您可以在源代码中获得峰值.定义是172行代码,因此不需要太多代码.它还必须实现该__reduce__方法以实现酸洗,因为它具有关于还需要被腌制和去除腌制的物品的顺序的信息.这是一个很好的例子,为什么你可能想要创建自己的dict子类,它增加了一个非常有用的功能,尊重添加到dict的值的顺序.