362 votes

Unicode (utf8) lire et écrire dans des fichiers en python

J'ai un peu de cerveau échec dans la compréhension de la lecture et de l'écriture d'un texte dans un fichier (Python 2.4).

# the string, which has an a-acute in it.
ss = u'Capit\xe1n'
ss8 = ss.encode('utf8')
repr(ss), repr(ss8)

("u'Capit\xe1n'", "'Capit\xc3\xa1n'")

print ss, ss8    
print >> open('f1','w'), ss8

>>> file('f1').read() 
'Capit\xc3\xa1n\n'

J'en Capit\xc3\xa1n dans mon éditeur de texte favori, dans le fichier f2.

alors:

>>> open('f1').read()
'Capit\xc3\xa1n\n'
>>> open('f2').read()
'Capit\\xc3\\xa1n\n'
>>> open('f1').read().decode('utf8')
u'Capit\xe1n\n'
>>> open('f2').read().decode('utf8')
u'Capit\\xc3\\xa1n\n'

Ce que je ne suis pas à comprendre ici? Clairement il y a quelques vital peu de magie (ou le bon sens) que je suis absent. Ce n'est qu'un type dans des fichiers texte pour obtenir les conversions.

Edit: Ce que je suis vraiment à défaut d'analyser ici, est ce que la pointe de l'UTF-8 est la représentation est, si vous ne pouvez pas obtenir Python à le reconnaître, quand on vient de l'extérieur. Peut-être que je devrais juste JSON vidage de la chaîne, et l'utiliser à la place, parce que cela a une asciiable représentation! Plus précisément, est-il une représentation ascii de cette unicode objet Python reconnaître et décoder, à partir d'un fichier? Si oui, comment puis-je l'obtenir?

>>> print simplejson.dumps(ss)
'"Capit\u00e1n"'
>>> print >> file('f3','w'), simplejson.dumps(ss)
>>> simplejson.load(open('f3'))
u'Capit\xe1n'

787voto

Tim Swast Points 3697

Plutôt que de jouer avec les coder, décoder les méthodes de je le trouve plus facile à utiliser la méthode open de l'codecs module.

>>>import codecs
>>>f = codecs.open("test", "r", "utf-8")

Puis, après l'appel de f read() de la fonction, une unicode codés objet est retourné.

>>>f.read()
u'Capit\xe1l\n\n'

Si vous connaissez l'encodage d'un fichier, en utilisant les codecs paquet va être beaucoup moins à confusion.

Voir http://docs.python.org/library/codecs.html#codecs.open

17voto

Gregg Lind Points 6905

Donc, j'ai trouvé une solution pour ce que je cherche, qui est:

 print open('f2').read().decode('string-escape').decode("utf-8")
 

Il y a quelques codecs inhabituels qui sont utiles ici. Cette lecture particulière permet de prendre des représentations utf-8 à partir de python, de les copier dans un fichier ASCII et de les lire en Unicode. Sous le décodage "chaîne-échappement", les barres obliques ne seront pas doublées.

Cela permet le type d'aller-retour que j'imaginais.

14voto

Ricardo Points 108
# -*- 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()

5voto

Torsten Marek Points 27554

Eh bien, votre éditeur de texte favori ne se rendent pas compte qu' \xc3\xa1 sont censés être les chaînes de caractères, mais il l'interprète en tant que texte. C'est pourquoi vous obtenez le double des barres obliques inverses dans la dernière ligne, c'est maintenant une vraie barre oblique inverse + xc3 etc dans votre fichier.

Si vous souhaitez lire et écrire des fichiers codés en Python, mieux utiliser les codecs module.

Coller du texte entre le terminal et des applications est difficile, parce que vous ne savez pas quel programme va interpréter votre texte à l'aide de lequel l'encodage. Vous pouvez essayer les suivantes:

>>> s = file("f1").read()
>>> print unicode(s, "Latin-1")
Capitán

Ensuite coller cette chaîne dans votre éditeur favori, et assurez-vous qu'il stocke en Latin-1. Sous l'hypothèse que le presse-papiers ne pas corrompre la chaîne, l'aller-retour devrait fonctionner.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X