2009-08-25 3 views
0

Quantities을 사용하여 단위와 함께 숫자를 정의 할 것을 고려하고 있습니다. 이 값은 디스크에 저장해야 할 가능성이 큽니다. 이미 알다시피 절규에는 중요한 문제가 하나 있습니다. 즉, 모듈을 재배치하면 언 피클 링에서 클래스를 해결할 수 없으므로 정보를 언 피클 링 해제 할 수 없습니다. 이 동작에 대한 대안이 있지만 실제로는 해결 방법입니다.안정적인 파이썬 직렬화 (예 : 피클 모듈 재배치 문제 없음)

이 문제에 대한 환상적인 해결책은 지정된 단위를 고유하게 인코딩하는 문자열을 만드는 것입니다. 디스크에서이 인코딩을 얻으면 Quantities 모듈의 팩토리 메서드에 전달하여 적절한 단위 인스턴스로 디코딩합니다. 장점은 모듈을 재배치하더라도 매직 문자열 토큰을 팩토리 메서드에 전달하는 한 모든 것이 여전히 작동한다는 것입니다.

이것은 알려진 개념입니까?

답변

1

Wheeler 's First Principle의 응용 프로그램처럼 보입니다. "컴퓨터 과학의 모든 문제는 다른 수준의 간접적 인 지시에 의해 해결 될 수 있습니다."(두 번째 원칙은 "하지만 그것은 보통 또 다른 문제를 만듭니다";-). 본질적으로해야 할 일은 유형 인을 식별하기위한 간접 검색입니다. 엔터티 유형은 피클 링 방식과 비슷합니다 (후자의 세부 사항은 pickle.pycopy_reg.py).

특히, 나는 당신이 원하는 것은 서브 클래스 pickle.Pickler이고, save_inst 메소드를 오버라이드한다고 생각한다. 현재 버전은 말한다 여기서

if self.bin: 
     save(cls) 
     for arg in args: 
      save(arg) 
     write(OBJ) 
    else: 
     for arg in args: 
      save(arg) 
     write(INST + cls.__module__ + '\n' + cls.__name__ + '\n') 

방금 ​​클래스의 모듈과 이름이 아닌 다른 무언가 쓰고 싶어 - 클래스의 (최대 2 개 문자열로 만들어진) 고유 식별자의 일종, 아마 자신의 레지스트리에서 개최 또는 레지스트리; 또한 save_global 메소드의 경우에도 마찬가지입니다.

그것을 _instantiate 부분이 이미 자신의 방법에서 고려되기 때문에, Unpickler의 하위 클래스에 대한 더욱 쉽게 :

def find_class(self, module, name): 
    # Subclasses may override this 
    __import__(module) 
    mod = sys.modules[module] 
    klass = getattr(mod, name) 
    return klass 

는 두 개의 문자열과 반환을해야되는 경우에만, find_class를 재정의해야 클래스 객체. 당신은 당신의 레지스트리를 통해 그것을 다시 할 수 있습니다.

항상 레지스트리가 관련되어있을 때와 마찬가지로 관심있는 모든 개체 (클래스)를 등록하는 방법을 고려해야합니다. 여기에 인기있는 전략 중 하나는 절임 만 남기고 모든 클래스 이동 , 모듈의 이름 변경 등은 영구적으로 기록됩니다; 이렇게하면 서브 클 래스 된 unpickler가 모든 작업을 수행 할 수 있으며 모든 등록 문제를 무시하고 가장 편리하게 오버라이드 된 find_class에서 모든 작업을 수행 할 수 있습니다. 나는이 문제를 "해결 방법"이라고 생각하지만, 나에게 이것은 "한 가지 더 많은 문제"를 피하는 "간접적 인 수준"을 극도로 간단하고 강력하며 편리하게 구현 한 것처럼 보입니다.