2016-05-04 9 views
0

私が尋ねた最初の質問はhow to load a pickle object and resolve certain referencesでした。私が直面している次の問題は、dumpsまたはloadsというオブジェクトをバイナリオブジェクトに呼び出すことができないということです。バイナリオブジェクトへのpersistent_idを持つpickleデータ(ダンプとロード)

以下はContextAwarePicklerContextAwareUnpicklerの実装です。オブジェクトをバイナリ表現に変換したり、変換したりするにはどうすればよいですか?私の知る限り、これはファイルに対してのみ機能します。 load_awaredump_aware

class ContextawarePickling : 

    @staticmethod 
    def load_aware (input_file,context=None) : 
     return ContextawareUnpickler(input_file).load() 

    @staticmethod 
    def dump_aware (object_to_save,output_file): 
     ContextawarePickler(output_file).dump(object_to_save) 

    @staticmethod 
    def loads_aware (stream,context=None) : 
     file = io.BytesIO(stream) 
     return ContextawarePickling.load_aware(file) 

    @staticmethod 
    def dumps_aware (object_to_save): 
     f = io.BytesIO() 
     ContextawarePickling.dump_aware(object_to_save,f) 
     return f.getvalue() 

基本的には最初の2つのユーティリティメソッドを作成します。

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") 

答えて

1

あなたのソリューションはdill(私は著者です)のものに似ていますが、堅牢ではありません。

https://github.com/uqfoundation/dill/blob/cccbea9b715e16b742288e1e5a21a687a4d4081b/dill/temp.py#L169(コードは以下に再現切り取ら)

def loadIO(buffer, **kwds): 
    """load an object that was stored with dill.temp.dumpIO 

    buffer: buffer object 

    >>> dumpfile = dill.temp.dumpIO([1, 2, 3, 4, 5]) 
    >>> dill.temp.loadIO(dumpfile) 
    [1, 2, 3, 4, 5] 
    """ 
    import dill as pickle 
    if PY3: 
     from io import BytesIO as StringIO 
    else: 
     from StringIO import StringIO 
    value = getattr(buffer, 'getvalue', buffer) # value or buffer.getvalue 
    if value != buffer: value = value() # buffer.getvalue() 
    return pickle.load(StringIO(value)) 

def dumpIO(object, **kwds): 
    """dill.dump of object to a buffer. 
Loads with "dill.temp.loadIO". Returns the buffer object. 

    >>> dumpfile = dill.temp.dumpIO([1, 2, 3, 4, 5]) 
    >>> dill.temp.loadIO(dumpfile) 
    [1, 2, 3, 4, 5] 
    """ 
    import dill as pickle 
    if PY3: 
     from io import BytesIO as StringIO 
    else: 
     from StringIO import StringIO 
    file = StringIO() 
    pickle.dump(object, file) 
    file.flush() 
    return file 

あなたはdillがするように、dump上のバッファflushのようなものには注意したいことがあります。

+0

このコードを共有していただきありがとうございます。私はこれが本当にこれを行うための再掘り起こしの方法だと思う。どうもありがとう。 –

0

私は答えを見つけたと思います。次に、loads_awaredumps_awareを実装できます。ここでは、データをロード/格納できるハンドラとして機能するio.BytesIOがラップされます。

関連する問題