2017-10-20 11 views
0

私は、ネストされた組み込みプリミティブ(リスト、辞書)とプロジェクトにもうないクラスのインスタンスから成るピクルされた構造を持っています。そのため、unpickling中にエラーが発生します。私はこれらのオブジェクトを本当に気にしないので、このネストされた構造体に格納されている数値を抽出できたらいいと思います。ファイルから取り除く方法はありますか。輸入の問題で壊れたものはすべてNoneと置き換えてください。ピクルの読み込み中にインポートエラーの原因となるオブジェクトを[なし]に置き換える方法はありますか?

私はUnpicklerから継承したクラスが見つからない場合Dummyを返すようにfind_class(self, module, name)を上書きしようとしていたが、何らかの理由で私はその後load reduceTypeError: 'NoneType' object is not callableを得続けます。

class Dummy(object): 
    def __init__(self, *argv, **kwargs): 
     pass 

私はたぶん、あなたはtryブロックで例外をキャッチし、あなたがやりたいことができ

class RobustJoblibUnpickle(Unpickler): 
    def find_class(self, _module, name): 
     try: 
      super(RobustJoblibUnpickle, self).find_class(_module, name) 
     except ImportError: 
      return Dummy 
+0

はあなたができると言っていますオブジェクトをピックルしますが、ピックルしませんか?ここではもっと広い仕事は何ですか? – roganjosh

+0

@roganjoshその構造(リストのdictsのリスト)は、しばらく前に漬け込み、その後コードベースが大幅に変更されました。今私はそれをunpickleしようとすると、そこに使用されているもののようなクラスがないので、私はインポートエラーに直面しますが、そこにオブジェクトを格納する必要はありませんが、数値と文字列だけでもうまくいくでしょう。だから、広範な問題は、私がそれをunpickleすることができないということです。 –

答えて

0

のようなものを試してみました( None にはいくつかのオブジェクトは、ダミークラスを使用する設定しますか)?

編集:

はこれを見てください、それはそれを行うための正しい方法であるかどうかは知りませんが、それが正常に動作するようです:

import sys 
import pickle 

class Dummy: 
    pass 

class MyUnpickler(pickle._Unpickler): 
    def find_class(self, module, name): # from the pickle module code but with a try 
     # Subclasses may override this. # we are doing it right now... 
     try: 
      if self.proto < 3 and self.fix_imports: 
       if (module, name) in _compat_pickle.NAME_MAPPING: 
        module, name = _compat_pickle.NAME_MAPPING[(module, name)] 
       elif module in _compat_pickle.IMPORT_MAPPING: 
        module = _compat_pickle.IMPORT_MAPPING[module] 
      __import__(module, level=0) 
      if self.proto >= 4: 
       return _getattribute(sys.modules[module], name)[0] 
      else: 
       return getattr(sys.modules[module], name) 
     except AttributeError: 
      return Dummy 

# edit: as per Ben suggestion an even simpler subclass can be used 
# instead of the above 

class MyUnpickler2(pickle._Unpickler): 
    def find_class(self, module, name): 
     try: 
      return super().find_class(module, name) 
     except AttributeError: 
      return Dummy 

class C: 
    pass 

c1 = C() 

with open('data1.dat', 'wb') as f: 
    pickle.dump(c1,f) 

del C# simulate the missing class 

with open('data1.dat', 'rb') as f: 
    unpickler = MyUnpickler(f) # or MyUnpickler2(f) 
    c1 = unpickler.load() 

print(c1) # got a Dummy object because of missing class 
+1

いいえ、オブジェクトを 'None'で置き換えた後、unpickleルーチンを"内部 "にしてunpickleルーチンを続けることが必要です –

+0

私の答えを見てください。これはあなたのために働きますか? – progmatico

+1

うん、私はそのようなものを試しました、私の問題はおそらく他の場所です。正しく理解すれば 'try .. catch'ブロックの中で' super()。find_class(s​​elf、module、name) 'を使うとさらに簡単に行えます。しかし、私の問題はどこかにあるようです。しかし、これを指摘してくれてありがとう。 –

関連する問題