2016-07-31 2 views
0

를 이진 문자열 목록을 작성 :변환하고이 코드의 파이썬 2.X 버전을 변환하기 위해 노력하고있어 파이썬 3

out_chunk = open('out.txt','w+b') 
chunks.append(out_chunk) # out_chunk is just a list of strings like ['a', 'b', ...] 
out_chunk.writelines(chunk) 

파이썬에 3.X 버전을. 내가 직접 파이썬 3.x를 위의 코드를 실행하면, 내가 예상되는 다음과 같은 오류를 얻을 :

Traceback (most recent call last): 
    File "C:/Users/Desktop/es/prog.py", line 145, in <module> 
    ob.external_sort() 
    File "C:/Users/Desktop/es/prog.py", line 70, in my_func 
    out_chunk.writelines(chunk) 
TypeError: a bytes-like object is required, not 'str' 

파이썬 3.x를 바이트로 문자열 목록을 작성하는 방법이 있나요? 아니면 그냥 문자열 목록으로 쓰기 (그리고 아마도, 성능 타격을?)한다

+0

그렇다면 왜 Python 3 버전에서 바이트 객체가 생성되지 않습니까? –

답변

3

파일을 바이너리 모드로 열었으므로 바이트를 인코딩해야합니다.

당신이 ('w+' 오히려 'w+b'에 비해 너무 개방) 파일 모드에서 'b' 부분을 삭제하는 경우, 당신은 당신이 인코딩을 부여하기위한 문자열을 인코딩 것 대신 TextIOBase interface의 구현을 얻을 (기본값은 결과를 사용하는 것입니다 locale.getdefaultencoding() 인 경우 open() 호출에 명시적인 encoding 인수를 제공해야합니다.

각 청크에 str.encode() method을 사용하여 수동으로 문자열을 인코딩 할 수도 있습니다. 그러나 TextIOBase 구현에 인코딩을 남기는 것은 조금 더 빨라지 겠지만, I/O 레이어는 각 str 청크에서 메소드 객체를 검색하지 않고 인코딩 할 수 없으며 결과 바이트를 Python bytes 객체에 박스로 묶어야합니다 다시.

또한 byte order mark이 필요한 인코딩의 경우 해당 마커를 파일 구현에 그대로 둡니다.

그러나 bytes 오브젝트을 처음 생성하는 경우 인코딩하지 않아도됩니다.

1

그냥 바이너리 모드로 파일을 열지 마십시오 :

out_chunk = open('out.txt','w+') 

는 희망이 도움이!

+0

그래, 알았어. 그러나 바이너리로 문자열 목록을 작성하면 단순히 텍스트 I/O를 작성하는 것과는 대조적으로 성능이 향상 될 수 있을지 궁금합니다. 다행히 파이썬 3.x 입출력 동작을 잘 아는 사람이 여기에 댓글을 달았을 수도 있습니다. :) 당신의 제안에 감사드립니다. – user1330974

+1

소문자 파이썬 릴리스에서 바꿀 수있는 소문자 최적화는 걱정하지 마십시오. Python3 (유니 코드) 문자열이 있고이를 텍스트 파일에 쓰고 싶다면 먼저 인코딩해야합니다. 명시 적 인코딩을 수행 한 다음 이진 파일에 쓸 수도 있고 TextIO 엔진에서 암시 적 인코딩을 수행 할 수도 있습니다. 어떤 방식 으로든 동일한 인코딩이 수행되므로 성능이 매우 비슷해야합니다. –

+1

@SergeBallesta : 글쎄, TextIOBase 구현은 각 청크에 대한'.encode' 속성을 해석 할 필요가 없으며 호출시 스택의 현재 프레임을 푸시하거나'bytes' 객체를 생성 할 필요가 없습니다 래핑 된 버퍼로 전달할 바이트를 C 배열로 남겨 둘 수 있습니다). –

관련 문제