Créer un fichier csv utf-8 en Python

Je ne peux pas créer un fichier csv utf-8 en Python.

je suis en train de le lire c'est docs, et dans le exemples, il dit:

Pour tous les autres codages suivants UnicodeReader et UnicodeWriter les classes peuvent être utilisées. Ils prennent un paramètre d'encodage supplémentaire dans leur constructeur et assurez-vous que le les données passent le lecteur réel ou l'écrivain codé en UTF-8:

Ok. J'ai donc ce code:

values = (unicode("Ñ", "utf-8"), unicode("é", "utf-8"))
f = codecs.open('eggs.csv', 'w', encoding="utf-8")
writer = UnicodeWriter(f)
writer.writerow(values)

Et j'obtiens cette erreur:

line 159, in writerow
    self.stream.write(data)
  File "/usr/lib/python2.6/codecs.py", line 686, in write
    return self.writer.write(data)
  File "/usr/lib/python2.6/codecs.py", line 351, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 22: ordinal not in range(128)

quelqu'un peut-il s'il vous plaît me donner une lumière pour que je puisse comprendre ce que je fais de mal puisque j'ai mis tous les encodages partout avant d'appeler la classe UnicodeWriter?

class UnicodeWriter:
    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        # Redirect output to a queue
        self.queue = cStringIO.StringIO()
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow([s.encode("utf-8") for s in row])
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        self.stream.write(data)
        # empty queue
        self.queue.truncate(0)

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)
17
demandé sur Somebody still uses you MS-DOS 2010-06-21 17:58:24

4 réponses

Vous n'avez pas à utiliser codecs.open;UnicodeWriter prend L'entrée Unicode et s'occupe de tout encoder en UTF-8. Lorsque UnicodeWriter écrit dans le gestionnaire de fichier que vous lui avez transmis, tout est déjà dans L'encodage UTF-8 (donc cela fonctionne avec un fichier normal que vous avez ouvert avec open).

En utilisant codecs.open, vous convertissez essentiellement vos objets Unicode en chaînes UTF-8 en UnicodeWriter, puis essayer de ré-encoder ces chaînes en UTF-8 à nouveau comme si ces chaînes contenaient des chaînes Unicode, ce qui évidemment échoue.

14
répondu Tamás 2010-06-21 14:19:54

Comme vous l'avez compris, il fonctionne si vous utilisez plaine ouverte.

la raison en est que vous avez essayé D'encoder UTF-8 deux fois. Une fois dans

f = codecs.open('eggs.csv', 'w', encoding="utf-8")
# ... and reencode it into the target encoding
data = self.encoder.encode(data)

pour vérifier que cela fonctionne utilisez votre code original et outcoment cette ligne.

Greetz

1
répondu KarlsFriend 2010-06-21 15:14:55

j'ai couru dans le csv / unicode défi un temps, et jeté sur bitbucket: http://bitbucket.org/famousactress/dude_csv .. pourrait travailler pour vous, si vos besoins sont simples :)

1
répondu royal 2010-06-21 21:34:31

Vous n'avez pas besoin de "double-encoder" tout ce.

votre application devrait fonctionner entièrement en Unicode.

Faites de votre encodage dans le codecs.open pour écrire des octets UTF-8 dans un fichier externe. Ne faites aucun autre encodage dans votre application.

0
répondu S.Lott 2010-06-21 14:15:19