[python] 파이썬에서 UTF-8 파일에 쓰기

나는 정말로와 혼동된다 codecs.open function. 내가 할 때 :

file = codecs.open("temp", "w", "utf-8")
file.write(codecs.BOM_UTF8)
file.close()

그것은 나에게 오류를 준다

UnicodeDecodeError : ‘ascii’코덱이 0 위치의 바이트 0xef를 디코딩 할 수 없습니다 : 서 수가 범위 내에 있지 않습니다 (128)

만약 내가한다면:

file = open("temp", "w")
file.write(codecs.BOM_UTF8)
file.close()

잘 작동합니다.

질문 은 왜 첫 번째 방법이 실패합니까? 그리고 어떻게 가슴을 삽입합니까?

두 번째 방법이 올바른 방법이라면 어떻게 사용 codecs.open(filename, "w", "utf-8")합니까?



답변

문제는 그것이 codecs.BOM_UTF8유니 코드 문자열이 아닌 바이트 문자열 이라는 것 입니다. 파일 핸들러가 “Unicode를 UTF-8로 인코딩 된 텍스트로 작성하려고하는데 바이트 문자열을주었습니다!”

바이트 순서 표시 (예 : 유니 코드 U + FEFF)의 유니 코드 문자열을 직접 작성하여 파일이 UTF-8로 인코딩하도록하십시오.

import codecs

file = codecs.open("lol", "w", "utf-8")
file.write(u'\ufeff')
file.close()

(정확한 대답을하는 것 같습니다-바이트가 EF BB BF 인 파일입니다.)

편집 : S. Lott 은 “utf-8-sig”를 인코딩하는 것이 BOM을 직접 작성하는 것보다 낫다는 제안 이지만, 이전에 무엇이 잘못되었는지 설명 하면서이 대답을 남겨 두겠습니다.


답변

다음을 읽으십시오 : http://docs.python.org/library/codecs.html#module-encodings.utf_8_sig

이 작업을 수행

with codecs.open("test_output", "w", "utf-8-sig") as temp:
    temp.write("hi mom\n")
    temp.write(u"This has ♭")

결과 파일은 예상 BOM이있는 UTF-8입니다.


답변

@ S-Lott는 올바른 절차를 제공하지만 유니 코드 문제를 확장 하면 Python 인터프리터는 더 많은 통찰력을 제공 할 수 있습니다.

Jon Skeet은 codecs모듈 에 대해 옳지 않습니다 ( 바이트 문자열이 포함되어 있습니다).

>>> import codecs
>>> codecs.BOM
'\xff\xfe'
>>> codecs.BOM_UTF8
'\xef\xbb\xbf'
>>> 

다른 니트를 선택 BOM하면 표준 유니 코드 이름이 있으며 다음과 같이 입력 할 수 있습니다.

>>> bom= u"\N{ZERO WIDTH NO-BREAK SPACE}"
>>> bom
u'\ufeff'

또한 다음을 통해 액세스 할 수 있습니다 unicodedata.

>>> import unicodedata
>>> unicodedata.lookup('ZERO WIDTH NO-BREAK SPACE')
u'\ufeff'
>>> 


답변

file * nix 명령을 사용하여 utf-8 파일에서 알 수없는 문자 세트 파일을 변환합니다

# -*- encoding: utf-8 -*-

# converting a unknown formatting file in utf-8

import codecs
import commands

file_location = "jumper.sub"
file_encoding = commands.getoutput('file -b --mime-encoding %s' % file_location)

file_stream = codecs.open(file_location, 'r', file_encoding)
file_output = codecs.open(file_location+"b", 'w', 'utf-8')

for l in file_stream:
    file_output.write(l)

file_stream.close()
file_output.close()


답변