Domanda

Sono molto confuso con il codecs.open function. Quando faccio:

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

E mi dà l'errore

  

UnicodeDecodeError: codec 'ascii' non può decodificare 0xEF byte in posizione   0: ordinale non nel campo (128)

Se faccio:

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

Funziona bene.

Domanda è il motivo per cui fa il primo metodo fallire? E come faccio a inserire il bom?

Se il secondo metodo è il modo corretto di farlo, ciò che il punto di usare codecs.open(filename, "w", "utf-8")?

È stato utile?

Soluzione

Credo che il problema è che codecs.BOM_UTF8 è una stringa di byte, non una stringa Unicode. Ho il sospetto che il gestore di file sta cercando di indovinare che cosa si intende realmente sulla base di "Io sono destinata ad essere la scrittura come testo Unicode UTF-8-encoded, ma mi avete dato una stringa di byte!"

Provare a scrivere la stringa Unicode per il segno di ordine dei byte (cioè Unicode U + FEFF) direttamente, in modo che il file appena codifica che, come UTF-8:

import codecs

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

(Che sembra dare la risposta giusta -. Un file con i byte EF BB BF)

EDIT: S. Lott suggerimento di utilizzare "utf-8-SIG", come la codifica è uno migliore di esplicitamente scrivere la distinta da soli, ma lascio questa risposta qui come spiega cosa stava succedendo sbagliato prima.

Altri suggerimenti

Leggi il seguente: http://docs.python.org/ biblioteca / codecs.html # modulo-encodings.utf_8_sig

A tale scopo

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

Il file risultante è UTF-8 con il BOM previsto.

@ S-Lott dà la procedura corretta, ma in espansione sulle Unicode problemi, il Python interprete in grado di fornire ulteriori delucidazioni.

Jon Skeet è giusto (insolito) sulla codecs modulo - contiene stringhe di byte:

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

Picking un'altra nit, il BOM ha uno standard Unicode nome, e può essere inserito come:

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

E 'accessibile anche tramite unicodedata :

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

Io uso il comando file * nix per convertire un file charset sconosciuto in un file 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()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top