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)
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.
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
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 :)
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.