2016-05-04 9 views
0

pickleを使用してバイナリファイルに書き込むオブジェクトがあるとします。のは、オブジェクトグラフは次のようになりましょう:pickleオブジェクトを読み込んで特定の参照を解決する方法

foo1 
+--->bar 
|  \--->context 
+--->baz 
|  +--->context 
|  \--->qux 
\--->context 

は今contextオブジェクトは、大きなデータ構造であり、quxのすべてのインスタンスは同じです。 (私たちのデザイン内の他のすべてのクラスをし、実際には)foobarbazが属するクラスのために

def __getstate__(self): 
    my_dict = dict(self.__dict__) 
    my_dict['context'] = None # We don't save the context 
    return my_dict 

:したがって、私たちはとピクルスプロセスのうち、これらのcontexxtのオブジェクトを残すことにしました。

load()オブジェクトをメモリに戻すと、すべてのcontext参照を指定したコンテキストに戻すことができます。オブジェクトツリーを再帰的に歩くことでこれを行うことができますが、pickleには、データをメモリにロードするときに値contextの値を埋め込むより洗練されたソリューションがあるかどうか疑問に思っていますか?

+0

あなたは[ '__setstate__']を探している(HTTPS ://docs.python.org/3/library/pickle.html#object.__setstate__)または何か不足していますか? –

+1

@IljaEverilä:問題は、 '__setstate__'にコンテキストを返すような追加パラメータがないことです。それにもかかわらず、私は* persistent pickling *(https://docs.python.org/3.2/library/pickle.html#pickle-persistent)で答えを見つけたと思います。 –

+1

ニースは、それを知らなかった(外側のオブジェクトサポートへの参照)。あなた自身の発見は行く道のように思える。 –

答えて

2

.contextではなくNonecontextを設定するので、あなたがpickleドキュメントのセクションPersistence of External Objectsからコードを適応させることができ、タイプContextである場合:

import pickle 

class ContextAwarePickler(pickle.Pickler): 
    def persistent_id(self, obj): 
     # if this is a context, return the key 
     if isinstance(obj, Context): 
      return ("Context", context.key) 

     # pickle as usual 
     return None 


class ContextAwareUnpickler(pickle.Unpickler): 
    def recover_context(self, key_id): 
     ... 

    def persistent_load(self, pid): 
     type_tag, key_id = pid 
     if type_tag == "Context": 
      return self.recover_context(key_id) 
     else: 
      raise pickle.UnpicklingError("unsupported persistent object") 
+0

ありがとうございます。質問をして数分後、例を見つけました。それにもかかわらず、変更されたコードは理解しやすくなります。 +1。 –

関連する問題