2013-08-28 5 views
2

Je lis dans un fichier CSV qui a UTF8 encodage:lecture UTF8 codé CSV et la conversion en UTF-16

ifile = open(fname, "r") 
for row in csv.reader(ifile): 
    name = row[0] 
    print repr(row[0]) 

Cela fonctionne bien, et imprime ce que je pense à imprimer; un UTF8 codé str:

> '\xc3\x81lvaro Salazar' 
> '\xc3\x89lodie Yung' 
... 

De plus, lorsque j'imprime simplement le str (par opposition à repr()) la sortie affiche ok (que je ne comprends pas Eitherway - devrait pas provoquer une erreur?):

> Álvaro Salazar 
> Élodie Yung 

mais lorsque je tente de convertir mon UTF8 codé strs-unicode:

ifile = open(fname, "r") 
for row in csv.reader(ifile): 
    name = row[0] 
    print unicode(name, 'utf-8') # or name.decode('utf-8') 

Je reçois l'inf amous:

Traceback (most recent call last):          
File "scripts/script.py", line 33, in <module> 
    print unicode(fullname, 'utf-8') 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xc1' in position 0: ordinal not in range(128) 

Je regardé les chaînes unicode qui sont créés:

ifile = open(fname, "r") 
for row in csv.reader(ifile): 
    name = row[0] 
    unicode_name = unicode(name, 'utf-8') 
    print repr(unicode_name) 

et la sortie est

> u'\xc1lvaro Salazar' 
> u'\xc9lodie Yung' 

Alors maintenant, je suis tout à fait confus que ceux-ci semblent être valeurs hexagonales mutilées. J'ai lu cette question:

et correctement apparaît que je fais tout, me conduit à croire que mon dossier est pas réellement UTF8, mais quand j'imprime d'abord les valeurs repr des cellules, ils semblent corriger les valeurs hexadécimales UTF8. Quelqu'un peut-il soit signaler mon problème ou d'indiquer où ma compréhension se délite (comme je commence à se perdre dans la jungle des encodages)


En aparté, je crois que je pourrais utiliser codecs pour ouvrir la fichier et le lire directement dans les objets Unicode, mais le module csv ne prend pas en charge unicode natif afin que je puisse utiliser cette approche.

Répondre

5

Votre encodage par défaut est ASCII. Lorsque vous essayez d'imprimer un objet unicode, l'interpréteur tente donc de l'encoder à l'aide du codec ASCII, qui échoue car votre texte inclut des caractères qui n'existent pas en ASCII.

La raison pour laquelle l'impression de la chaîne codée UTF-8 ne produit pas d'erreur (ce qui semble vous perturber, bien qu'elle ne le devrait pas) est que cela envoie simplement les octets à votre terminal. Il ne produira jamais une erreur Python, bien que cela puisse produire une sortie moche si votre terminal ne sait pas quoi faire avec les octets. Pour imprimer un code unicode, utilisez print some_unicode.encode('utf-8'). (Ou quel que soit l'encodage utilisé par votre terminal).

Comme pour le u'\xc1lvaro Salazar', rien ici n'est mutilé.Le caractère Á est au codepoint unicode C1 (qui n'a rien à voir avec la représentation UTF-8, mais qui a la même valeur que Latin-1), et Python utilise \x hex escape au lieu de \u notation unicode codepoint pour les codespoints qui aurait 00 comme le plus important octet pour économiser l'espace (il pourrait aussi avoir affiché ce que \u00c1.)

pour obtenir un bon aperçu de la façon dont fonctionne Unicode en Python, je suggère http://nedbatchelder.com/text/unipain.html

+0

Hey merci. Cela a beaucoup aidé. Tout commence à se mettre en place - comment python (et l'interpréteur + stdout) gère unicode etc ... me confondait mais je pense que c'est clair maintenant. Cette vidéo est également excellente. –