2017-10-20 19 views
0

필자는 중첩 된 기본 제공 프리미티브 (목록, 사전)와 더 이상 프로젝트에없는 클래스의 인스턴스로 구성되어 피클링되지 않는 동안 오류를 일으키는 피클링 된 구조를가집니다. 나는 그 객체들을 정말로 신경 쓰지 않는다. 나는이 중첩 된 구조체에 저장된 수치 값들을 추출 할 수 있었으면 좋겠다. 파일에서 unpickle을 수행하고 가져 오기 문제로 인해 손상된 모든 것을 바꿀 수있는 방법이 있습니까? 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 블록에서 예외를 catch하고, 당신이 원하는 무엇을 할 수

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 루틴을 "내부"로 수행해야합니다. –

+0

내 대답을 참조하십시오. 이 방법이 효과가 있습니까? – progmatico

+1

그래, 나는 그와 비슷한 것을 시도했다. 나의 이슈는 아마도 어딘가에있을 것이다; 올바르게 이해하면'try .. catch' 블록 안에'super(). find_class (self, module, name)'을 사용하면 더 쉽게 할 수 있습니다. 하지만 내 문제는 어딘가에있는 것 같습니다. 이 점을 지적 해 주셔서 감사합니다. –