Question

Je suis vraiment confondu avec le codecs.open function. Quand je fais:

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

Il me donne l'erreur

  

UnicodeDecodeError: codec 'ascii' ne peut pas décoder octet 0xEF en position   0: ordinal dans la plage (128)

Si je fais:

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

Il fonctionne très bien.

Question est pourquoi la première méthode a échoué? Et comment puis-je insérer le bom?

Si la deuxième méthode est la bonne façon de le faire, ce que le point d'utiliser codecs.open(filename, "w", "utf-8")?

Était-ce utile?

La solution

Je crois que le problème est que codecs.BOM_UTF8 est une chaîne d'octets, pas une chaîne Unicode. Je soupçonne que le gestionnaire de fichiers tente de deviner ce que vous voulez vraiment dire basé sur « Je suis censé être écrit sous forme de texte Unicode UTF-8 codé, mais vous me avez donné une chaîne d'octets! »

Essayez d'écrire la chaîne de caractères Unicode pour la marque d'ordre d'octet (à savoir Unicode U + FEFF) directement, de sorte que le fichier code juste que UTF-8:

import codecs

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

(Cela semble donner la bonne réponse -. Un fichier avec des octets EF BB BF)

EDIT: S. Lott suggestion d'utiliser "utf-8-sig" comme l'encodage est un meilleur que écrire explicitement la nomenclature vous-même, mais je vais laisser cette réponse ici car il explique ce qui se passait mal avant.

Autres conseils

Lisez ce qui suit: http://docs.python.org/ bibliothèque / codecs.html # module encodings.utf_8_sig

Pour ce faire,

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

Le fichier résultant est UTF-8 avec la nomenclature attendue.

@ S-Lott donne la bonne procédure, mais en expansion sur les Unicode questions, l'interprète Python peut fournir plus d'idées.

Jon Skeet est juste (inhabituel) sur le codecs Module - il contient des chaînes d'octets:

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

Choisir une autre petite bête, le BOM a une norme Unicode nom, et il peut être entré comme:

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

Il est également accessible via unicodedata :

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

J'utilise le fichier * commande nix pour convertir un fichier charset inconnu dans un fichier 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()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top