1

私はクラスの継承をいじっていて、クラス辞書でデータをピクルする方法にこだわっています。

自己の辞書部分のみをダンプする場合、辞書を自己にロードすると、自己はクラスではなく辞書型になります。しかし、クラス全体をピクルすると、エラーが発生します。

エラー

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

1 に答える 1

5

dict のサブクラスである model と呼ばれるクラスを持ち、適切に pickle 化してモデル型のオブジェクトに unpickle することだけが必要な場合は、特別なことをする必要はありません。追加および削除するために例で定義したメソッドは不要です。他の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'> {}

以下は、おそらくあなたが達成しようとしていたものとより一致している別のバージョンです。しかし、この方法で物事を行うべきではありません。load メソッドは奇妙で、save も同様です。以下のコードを使用して、実行できることを示しますが、非常に混乱するため、実際にはやりたいことではありません。

別のバージョン (これは行わないでください)

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

参考文献

picklable である dict のサブクラスの良い例はcollections.OrderedDictです。これは python 標準ライブラリの一部であり、python で実装されているため、ソースでピークを迎えることができます。定義は 172 行のコードなので、コードが多すぎて調べる必要はありません。また、__reduce__ピクルス化およびピクルス化を解除する必要があるアイテムの順序に関する情報があるため、ピクルス化を実現するためのメソッドを実装する必要がありました。これは、辞書の独自のサブクラスを作成したい理由の良い例です。辞書に追加された値の順序を尊重するという非常に便利な機能が追加されています。

于 2012-11-30T06:15:09.393 に答える