2017-05-03 14 views
2

에 의해 사이 ​​썬 확장을 저장 python이하고 모델을 만들고 훈련하는 데 사용하지만, 나는 그것이 나에게이 잘못을 준다 pickle를 사용하여 내 모델을 저장하고자 할 때 :이 같은 <code>cython</code>로 작성된 클래스 또는 확장 유형이 피클

TypeError: can't pickle som.Self_Organized_Map objects

피클 또는 m 잘못 무엇을 y 코드? pickle cant는 확장 오브젝트를 저장합니까?

+1

많은 문서와 이전 질문은 읽지 않은 것처럼 보입니다. 예 : https://docs.python.org/3/library/pickle.html#what-can-be- pickle-and-unpickled ([확장 유형은 기본적으로'__dict__'을 정의하지 않습니다.} (http://cython.readthedocs.io/en/latest/src/reference/extension_types.html#attributes)). 관련성 높은 이전 질문 : http://stackoverflow.com/questions/12646436/pickle-cython-class http://stackoverflow.com/questions/36301322/pickle-cython-class-with-c-pointers – DavidW

+1

또한 제목에는 포인터가 언급되어 있지만 코드에는 아무 것도 표시되지 않습니다. 아마 분명히 해줄까요? – DavidW

+0

@DavidW 고마워. 고마워. –

답변

2

Cython 0.26 (2017 년 7 월에 발표 됨) 이후 cdef 클래스는 포인터 또는 공용체가 포함되어 있지 않으면 자동으로 절이 수 있습니다. 구조체가 포함 된 클래스의 경우 자동 산세는 @cython.auto_pickle(True) 데코레이터로 활성화 할 수 있습니다. 다른 이유 때문에 코드 오버 헤드가 높기 때문에 기본적으로 비활성화되어 있습니다.

자세한 내용은 changelogthe website of Stefan Behnel에서 확인할 수 있습니다.

4

Cython 클래스는 기본적으로 pickleable이 아니므로 Pickle interface을 직접 구현해야합니다. 여러 가지 단계를 수행 할 수 있지만 __getstate____setstate__은 가장 사용자에게 친숙한 수준이므로 그렇지 않으면 좋은 이유가없는 한 시작하는 것이 좋습니다.

클래스의 내용을 pickleable로 만들려면 __getstate__에 터플을 반환하고 그 반대로는 __setstate__으로 반환하는 것만 큼 쉽습니다. Memoryviews 자체는 pickleable이 아니지만 base 속성을 가질 수 있습니다.

cdef class C: 
    cdef double[:] array 
    cdef python_obj 
    cdef int integer 

    def __init__(self,array,python_obj,integer): 
     self.array = array 
     self.python_obj = python_obj 
     self.integer = integer 

    def __getstate__(self): 
     return (self.array.base, # memoryviews aren't pickleable, need to get underlying object 
          # and hope it's pickleable 
       self.python_obj, self.integer) 

    def __setstate__(self,x): 
     self.array, self.python_obj, self.integer = x 

클래스에 C 또는 C++ 객체가 있으면 훨씬 더 복잡합니다. 간단한 유형의 경우 시작하기 좋은 곳은 메모리를 bytearray에 복사하거나 Cython의 기본값 인 struct<->dict 상호 변환을 이용하는 것입니다. 그러나 클래스에 포인터가 포함되어 있으면이 방법이 작동하지 않으므로 C/C++에서 신뢰할 수있는로드/저장 메커니즘을 구현해야합니다.