Estoy realmente confundido con el codecs.open function
. Cuando lo hago:
file = codecs.open("temp", "w", "utf-8")
file.write(codecs.BOM_UTF8)
file.close()
Me da el error
UnicodeDecodeError: el códec 'ascii' no puede decodificar el byte 0xef en la posición 0: el ordinal no está en el rango (128)
Si lo hago:
file = open("temp", "w")
file.write(codecs.BOM_UTF8)
file.close()
Funciona bien.
La pregunta es ¿por qué falla el primer método? ¿Y cómo inserto el bom?
Si el segundo método es la forma correcta de hacerlo, ¿cuál es el punto de usar codecs.open(filename, "w", "utf-8")
?
python
utf-8
byte-order-mark
John Jiang
fuente
fuente
Respuestas:
Creo que el problema es que
codecs.BOM_UTF8
es una cadena de bytes, no una cadena Unicode. Sospecho que el controlador de archivos está tratando de adivinar lo que realmente quieres decir en base a "¡Estoy destinado a escribir Unicode como texto codificado en UTF-8, pero me has dado una cadena de bytes!"Intente escribir la cadena Unicode para la marca de orden de bytes (es decir, Unicode U + FEFF) directamente, de modo que el archivo solo codifique eso como UTF-8:
(Eso parece dar la respuesta correcta: un archivo con bytes EF BB BF).
EDITAR: la sugerencia de S. Lott de usar "utf-8-sig" como codificación es mejor que escribir explícitamente la lista de materiales, pero dejaré esta respuesta aquí, ya que explica lo que estaba sucediendo antes.
fuente
codecs.open
lugar de soloopen
Lea lo siguiente: http://docs.python.org/library/codecs.html#module-encodings.utf_8_sig
Hacer esto
El archivo resultante es UTF-8 con la lista de materiales esperada.
fuente
temp.close()
?open
.@ S-Lott ofrece el procedimiento correcto, pero al ampliar los problemas de Unicode , el intérprete de Python puede proporcionar más información.
Jon Skeet tiene razón (inusual) sobre el
codecs
módulo: contiene cadenas de bytes:Al elegir otra liendre,
BOM
tiene un nombre Unicode estándar y se puede ingresar como:También es accesible a través de
unicodedata
:fuente
Uso el comando file * nix para convertir un archivo charset desconocido en un archivo utf-8
fuente
# coding: utf8
lugar de lo# -*- coding: utf-8 -*-
cual es mucho más fácil de recordar.