2017-10-20 97 views
0

我有一个由嵌套的内置原语(列表,字典)和不在项目中的类的实例组成的pickled结构,因此在取出过程中会导致错误。我并不关心这些对象,我希望能够提取存储在这个嵌套结构中的数值。有没有办法从文件中取消选中,并替换因导入问题导致的所有内容,例如None如何在pickle加载过程中将导致导入错误的对象替换为None?

我试图从Unpickler继承和覆盖find_class(self, module, name)返回Dummy如果类不能被发现,但由于某种原因,我一直在后load reduce越来越TypeError: 'NoneType' object is not callable

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

我想是这样

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结构(清单的词典列表)被腌制了一段时间,从那以后代码库发生了显着变化;现在如果我试图取消它,我面临导入错误,因为没有像那里使用的类,虽然我不需要存储在那里的对象,即使只有数值和字符串,我也会很好;所以,是的,广泛的问题是,我不能undeckle它 –

回答

0

也许你能赶上在try块中的例外,做你想做的( 设置一些对象 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

好吧,你需要以某种方式做“内”unickickle例程继续undeketling替换对象后用'None' –

+0

看到我的答案编辑。这对你有用吗? – progmatico

+1

是的,我尝试过这样的事情,我的问题可能在别的地方;如果我理解正确,那么可以使用'super()。find_class(s​​elf,module,name)''try ... catch'块内的内容来完成它。但我的问题似乎在别的地方。感谢您指出这一点,但。 –

相关问题