2011-08-24 5 views
27

파이썬의 피클 잠금 장치, 파일 객체 등 피클 수 없습니다 (I 표준 파이썬 여기에 2.5/2.6/2.7이 말하는거야)발전기를 절인해서 사용할 수없는 이유는 무엇입니까?

그것은 또한하지 피클 발전기 및 람다 표현식 (또는 다른 익명 코드) 수 피클 때문에 정말 이름 참조 만 저장합니다.

잠금 및 OS 종속 기능의 경우 이유을 피할 수없는 이유는 분명한 사실입니다.

그러나 왜 당신은 발전기를 절 이라요?


: 단지 명확성을 위해 - 나는 근본적인 이유에 관심이 있어요 (또는 가정하고 디자인 결정에 갔다 선택) 하지 "에서 당신에게 제공하기 때문에 피클 오류".

나는 조금 더 넓은 목표를 가지고 있기 때문에, 여기에 당신이 대답했는지 여부에 대한 경험 법칙이 있습니다 : "이러한 가정이 제기되거나, 허용 된 발전기의 유형이 어떻게 더 제한되어 있다면 산 세척 발전기가 다시 작동합니까?"

+1

발전기를 피클 링하는 것이 언제 의미가 있습니까? – NullUserException

+10

@NullUser : 상상하기가 너무 어렵지 않습니다. 하나를 반복하면서 프로그램을 중단하고 나중에 중단 한 부분부터 다시 시작하려고합니다. –

+3

... 동시에 또는 다른 프로그램에서 재개하십시오 (= 직렬화는 네트워크 전송에도 사용됩니다) – Radim

답변

39

많은 정보가 있습니다. 문제에 대한 "공식 단어"는 (closed) Python bugtracker issue을 참조하십시오.

결정을 내린 사람들 중 하나에 의해 핵심 논리는, this blog에 자세히 설명되어 있습니다 :

발전기는 기본적으로 재미있게 기능, 우리는 어떤 그 바이트 코드를 저장해야하기 때문에 파이썬의 버전과 지역 변수, 클로저 및 명령어 포인터와 같은 생성기의 상태를 유지하는 프레임 사이의 역 호환을 보장하지 않습니다. 그리고이 후자는 기본적으로 성취하기가 번잡합니다. 왜냐하면 기본적으로 전체 통역사를 선택 가능하게 만들어야하기 때문입니다. 따라서 산세 발생기에 대한 지원은 CPython의 핵심을 상당 부분 변경해야합니다.

피클에서 지원되지 않는 객체 (예 : 파일 핸들, 소켓, 데이터베이스 연결 등)가 생성기의 로컬 변수에서 발생하면 피클 지원에 관계없이 해당 생성기를 자동으로 절편 할 수 없습니다 우리가 구현할 수도있는 발전기에 대해서. 따라서이 경우에도 사용자 정의 __getstate____setstate__ 메소드를 제공해야합니다. 이 문제는 발전기에 대한 산세 처리를 다소 제한적으로 만듭니다.

그리고 두 사람은 해결 방법이 언급 제안 :

어쨌든, 당신은 같은 기능을 위해 필요한 경우, 다음 위의 모든 수행 스택리스 파이썬으로 본다. Stackless의 인터프리터는 picklable이므로 프로세스 마이그레이션을 무료로받을 수 있습니다. 즉, 태스크 릿 (Stackless의 녹색 스레드 이름)을 인터럽트하고, 피클을 다른 시스템으로 보내고, unpickle하고, 태스크 릿을 다시 시작하고, 프로세스를 마이그레이션 한 것을 나타낼 수 있습니다. 이것은 괴물이 멋진 기능입니다!

제 생각에는 단순한 반복기 (예 : __next__ 메서드가있는 생성기)로 생성자를 다시 작성하는 것이 가장 좋은 해결책입니다. 반복자는 자신의 상태가 명백하기 때문에 피클을 쉽고 효율적으로 공간별로 볼 수 있습니다. 그러나 여전히 외부 상태를 나타내는 객체를 명시 적으로 처리해야합니다. 너는이 문제를 해결할 수 없다.

+0

우수 답변, 감사합니다. 나는 "generator_tools"라는 순수 파이썬 패키지를 발견했다. 나는 그것을 작동시킬 수 없다, 그래서 나는 당신과 Alexandre가 맞을 것이라고 생각한다 ... – Radim

+0

그 패키지는 http://metaoptimize.com/blog/2009/12/22/why-cant-you에 언급되어있다. -pickle-generators-in-python-workaround-for-saving-training-state/또 다른 해결 방법 패턴이 있습니다. – agf

+1

답변을 제공하고 동시에 "가까운"투표를 할 수 있습니까? 이제 나는 "논쟁, 논쟁 및 토론 확대"를 기이하게 기다리고 있습니다 :-) – Radim

19

실제로 구현할 수 있습니다. PyPyStackless Python 모두 (어쨌든 어느 정도)이 허용 : CPython의에서

Python 2.7.1 (dcae7aed462b, Aug 17 2011, 09:46:15) 
[PyPy 1.6.0 with GCC 4.0.1] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
And now for something completely different: ``Not your usual analyses.'' 
>>>> import pickle 
>>>> gen = (x for x in range(100)) 
>>>> next(gen) 
0 
>>>> pickled = pickle.dumps(gen) 
>>>> next(pickle.loads(pickled)) 
1 

그것은 pickable 발전기를 시뮬레이션하기 위해 iterator object을 만들 수도 있습니다.

+0

-1 : 모두 사실이지만 다른 질문에 답변합니다. – Radim

+1

@Radim 그것은 _my_ 질문에 답했습니다. –

관련 문제