utf8 - encoding utf-8 python 3
Escribir en el archivo UTF-8 en Python (4)
@ 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 módulo de codecs
: contiene cadenas de bytes:
>>> import codecs
>>> codecs.BOM
''/xff/xfe''
>>> codecs.BOM_UTF8
''/xef/xbb/xbf''
>>>
Escogiendo otro nit, el BOM
tiene un nombre Unicode estándar, y se puede ingresar como:
>>> bom= u"/N{ZERO WIDTH NO-BREAK SPACE}"
>>> bom
u''/ufeff''
También se puede acceder a través de unicodedata
:
>>> import unicodedata
>>> unicodedata.lookup(''ZERO WIDTH NO-BREAK SPACE'')
u''/ufeff''
>>>
Estoy realmente confundido con la 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, ¿para qué codecs.open(filename, "w", "utf-8")
?
Creo que el problema es que codecs.BOM_UTF8
es una cadena de bytes, no una cadena Unicode. Sospecho que el manejador de archivos está tratando de adivinar lo que realmente quieres decir, basado en "¡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 simplemente codifique eso como UTF-8:
import codecs
file = codecs.open("lol", "w", "utf-8")
file.write(u''/ufeff'')
file.close()
(Eso parece dar la respuesta correcta: un archivo con bytes EF BB BF.)
EDITAR: suggestion de S. Lott de usar "utf-8-sig" ya que la codificación es mejor que escribir explícitamente la BOM, pero dejaré esta respuesta aquí ya que explica lo que estaba pasando mal antes.
Lea lo siguiente: http://docs.python.org/library/codecs.html#module-encodings.utf_8_sig
Hacer esto
with codecs.open("test_output", "w", "utf-8-sig") as temp:
temp.write("hi mom/n")
temp.write(u"This has ♭")
El archivo resultante es UTF-8 con la lista de materiales esperada.
Uso el comando file * nix para convertir un archivo charset desconocido en un archivo 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()