Estou realmente confuso com o codecs.open function
. Quando eu faço:
file = codecs.open("temp", "w", "utf-8")
file.write(codecs.BOM_UTF8)
file.close()
Isso me dá o erro
UnicodeDecodeError: o codec 'ascii' não pode decodificar o byte 0xef na posição 0: ordinal fora do intervalo (128)
Se eu fizer:
file = open("temp", "w")
file.write(codecs.BOM_UTF8)
file.close()
Funciona bem.
A pergunta é por que o primeiro método falha? E como insiro o bom?
Se o segundo método é a maneira correta de fazê-lo, qual o sentido de usar codecs.open(filename, "w", "utf-8")
?
python
utf-8
byte-order-mark
John Jiang
fonte
fonte
Respostas:
Acredito que o problema é que
codecs.BOM_UTF8
é uma sequência de bytes, não uma sequência Unicode. Eu suspeito que o manipulador de arquivos está tentando adivinhar o que você realmente quer dizer com base em "Eu devo escrever Unicode como texto codificado em UTF-8, mas você me forneceu uma string de bytes!"Tente escrever a sequência Unicode para a marca de ordem dos bytes (ou seja, Unicode U + FEFF) diretamente, para que o arquivo codifique apenas como UTF-8:
(Isso parece dar a resposta certa - um arquivo com bytes EF BB BF.)
EDIT: A sugestão de S. Lott de usar "utf-8-sig" como a codificação é melhor do que escrever explicitamente a BOM, mas deixarei esta resposta aqui, pois explica o que estava errado antes.
fonte
codecs.open
vez de apenas #open
Leia o seguinte: http://docs.python.org/library/codecs.html#module-encodings.utf_8_sig
Faça isso
O arquivo resultante é UTF-8 com a lista técnica esperada.
fonte
temp.close()
?open
.O @ S-Lott fornece o procedimento correto, mas, expandindo os problemas de Unicode , o intérprete Python pode fornecer mais informações.
Jon Skeet está certo (incomum) sobre o
codecs
módulo - ele contém seqüências de bytes:Escolhendo outro nit, ele
BOM
tem um nome Unicode padrão e pode ser inserido como:Também é acessível via
unicodedata
:fonte
Eu uso o comando file * nix para converter um arquivo charset desconhecido em um arquivo utf-8
fonte
# coding: utf8
vez do# -*- coding: utf-8 -*-
que é muito mais fácil de lembrar.