我正在玩类继承,我一直在研究如何在类字典中腌制数据。
如果仅转换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()
答案 0 :(得分:5)
如果您想要做的就是拥有一个名为model的类,它是dict的子类,并且可以正确地pickle和unpickled回到类型为model的对象,那么您不需要做任何特殊的事情。您在示例中定义的添加和删除方法是不必要的,您可以直接在模型实例上执行这些方法,就像使用任何其他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
<强>输出强>
<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的值的顺序。