2014-11-17 5 views
0

에 pickle.dumps 출력 쓰기 : 파이썬 3이 코드를 인쇄 트루에서나는 다음과 같은 코드가 파일

some_dict = {'a':0, 'b':1} 
line = "some_dict_b = %s\n" % pickle.dumps(some_dict,2) 
exec(line) 
decoded_dict = pickle.loads(some_dict_b) 
decoded_dict == some_dict 

합니다. 파이썬 2 (2.7.8)에서 나는 exec 라인에 오류가 발생한다. 나는 덤프가 2.7에서 바이트 스트림을 반환하는 동안 str을 반환한다는 것을 안다.

입력 파일의 데이터를 분석 한 다음 특정 메모리 객체를 만들고 이러한 객체를 사용하는 python 스크립트를 작성해야하는 프로그램을 작성하고있다. 필자는 pickle.dumps()를 사용하여 스크립트 파일에 이러한 객체를 작성하고 위에서 스케치 한 아이디어에 따라 변수 선언 행에 삽입합니다. 하지만 파이썬에서이 코드를 실행 할 수 있어야합니다 2.

내가 한 파이썬 3 라인의 변수를 가져 각 백 슬래시가 제대로 탈출 유형 것을주의 :

>>> line 
"some_dict_b = b'\\x80\\x02... 

파이썬 2에서 난다면 :

>>> line 
'some_dict_b = \x80\x02... 

답변

1

파이썬 3 bytes 유형은 %s으로 문자열로 변환하지 않을 때 문자열 표현에, 그래서는 객체 표현이 대신 사용됩니다 가지고있다. 객체에서 파이썬 호환 구문을 생성하려면 대신 표현식을 직접 사용하기 위해 %r 형식화기를 사용할 수 있습니다. 파이썬 2에서

:

파이썬 3에서
>>> import pickle 
>>> some_dict = {'a':0, 'b':1} 
>>> p = pickle.dumps(some_dict, 2) 
>>> print 'string: %s\nrepresentation: %r' % (p, p) 
string: ?}q(UaqKUbqKu. 
representation: '\x80\x02}q\x00(U\x01aq\x01K\x00U\x01bq\x02K\x01u.' 

:

>>> import pickle 
>>> some_dict = {'a':0, 'b':1} 
>>> p = pickle.dumps(some_dict, 2) 
>>> print('string: %s\nrepresentation: %r' % (p, p)) 
string: b'\x80\x02}q\x00(X\x01\x00\x00\x00bq\x01K\x01X\x01\x00\x00\x00aq\x02K\x00u.' 
representation: b'\x80\x02}q\x00(X\x01\x00\x00\x00bq\x01K\x01X\x01\x00\x00\x00aq\x02K\x00u.' 

개체 표현을 일반적으로 표현을 제공하려고 시도합니다 (object.__repr__ special method를 사용하는 repr() function의 출력)이 Python 스크립트 나 대화 형 프롬프트에 다시 붙여 넣어 같은 값을 다시 만들 수 있습니다. repr()에 대한 문서에서

: 많은 유형의

,이 기능은 다른 표현이 문자열 묶여 eval()에 전달하면 동일한 값을 가진 객체를 생성 할 문자열을 반환하려는 시도를한다 꺽쇠 괄호 안에는 객체의 이름과 주소를 포함하는 추가 정보와 함께 객체 유형의 이름이 포함됩니다.

아무 것도 pickle에만 해당됩니다.

+0

철저한 설명 주셔서 감사하지만 왜 파이썬 3에서 코드가 작동합니까? 객체의 문자열과 표현보기가 일치한다는 것은 단지 우연의 일치입니까? –

+0

@ ErwinLavalliére : 문자열 표현이 없으면 (__str__ 메소드 없음) 대신'__repr__'이 사용됩니다. 그것이 전혀 효과가 있었다는 것은 우연의 일치였습니다. :-) –

0

"나는 exec를 사용합니다"라고 생각할 때마다 다시 생각하십시오. 너는하지 않는다. 이와 같이 데이터를 평가하는 대신 데이터의 내용을 dict 자체에 저장하십시오.

그런 다음 변수에 데이터를 명시 적으로 할당하십시오.

some_dict = {'a':0, 'b':1} 
line = pickle.dumps(some_dict) 
decoded_dict = pickle.loads(line) 
decoded_dict == some_dict 
+0

나는 조금 일찍 제출했다. – deets

+0

나는 당신이 말하는 것을 이해하지만 그것은 내가 원하는 것만은 아니다. 아시다시피, 나는 파이썬 변수 지정 문에 다음과 같이 덤프 출력을 작성하고 싶습니다. "line = "이것은 나중에 실행될 수 있으며 다른 컴퓨터에서도 실행됩니다. –

+0

왜 이걸 원하니? exec의 보안 함축 외에도 (나는 끔찍한), 임의로 생성 된 변수를 의미있게 다루는 코드를 가질 수 있다고 생각하지 않습니다. 따라서 어떤 변수가 필요한지 알거나 그 값을 저장하고로드에 할당하면 안됩니다. 그렇지 않으면 어쨌든 동적 데이터 구조가 필요합니다. – deets

0

문자열 또는 바이트 개체를 호출하기 전에 repr을 호출 할 수 있습니다.

# Python 2 
>>> 'some_dict = %s' % repr(pickle.dumps(d)) 
'some_dict = "(dp0\\nS\'a\'\\np1\\nI12\\nsS\'b\'\\np2\\nI24\\ns."' 

# Python 3 
>>> 'some_dict = %s' % repr(pickle.dumps(d)) 
"some_dict = b'\\x80\\x03}q\\x00(X\\x01\\x00\\x00\\x00bq\\x01K\\x18X\\x01\\x00\\x00\\x00aq\\x02K\\x0cu.'" 

또는 자동 repr 전화를 !r를 사용하여 format 방법을 사용하십시오

>>> 'some_dict = {!r}'.format(pickle.dumps(d)) 
"some_dict = b'\\x80\\x03}q\\x00(X\\x01\\x00\\x00\\x00bq\\x01K\\x18X\\x01\\x00\\x00\\x00aq\\x02K\\x0cu.'" 

은 (또한 파이썬 2에서 작동)

관련 문제