So schreiben Sie UTF-8 in eine CSV-Datei

82

Ich versuche, aus einem PyQt4 eine Textdatei im CSV-Format zu erstellen QTableWidget. Ich möchte den Text mit einer UTF-8-Codierung schreiben, da er Sonderzeichen enthält. Ich benutze folgenden Code:

import codecs
...
myfile = codecs.open(filename, 'w','utf-8')
...
f = result.table.item(i,c).text()
myfile.write(f+";")

Es funktioniert so lange, bis die Zelle ein Sonderzeichen enthält. Ich habe es auch mit versucht

myfile = open(filename, 'w')
...
f = unicode(result.table.item(i,c).text(), "utf-8")

Es hört aber auch auf, wenn ein Sonderzeichen erscheint. Ich habe keine Ahnung, was ich falsch mache.

Martin
quelle
"es ist auch oben"? Was bedeutet das? Welchen Fehler bekommen Sie? Was ist dein Input?
Die Eingabe ist ein pyqt4 QTableWidgetItem. Das Problem ist, dass ich keinen Fehler bekomme, weil das Skript als Plugin ausgeführt wird.
Martin
Versuchen Sie dann, das Problem außerhalb von QT zu reproduzieren.
Die Lösung gefunden. Ich musste schreibenmyfile.write(u"%s"&f+";")
Martin

Antworten:

105

Von Ihrem Shell-Lauf:

pip2 install unicodecsv

Und (im Gegensatz zur ursprünglichen Frage) vorausgesetzt, Sie verwenden Pythons eingebautes csv Modul verwenden, verwandeln Sie
import csvsich
import unicodecsv as csvin Ihren Code.

kqw
quelle
28
Es funktionierte nicht nur durch Ersetzen des Imports, ich musste auch die Codierung beim Erstellen des Writers hinzufügen: writer = csv.writer(out, dialect='excel', encoding='utf-8')und den Datei-Handler mit erstellen open(..., nicht codecs.open(... .
Suzana
4
Ich habe alle Vorschläge für StackOverflow ausprobiert und nur dieser funktioniert für mich.
Charles Chow
87

Es ist sehr einfach für Python 3.x ( docs ).

import csv

with open('output_file_name', 'w', newline='', encoding='utf-8') as csv_file:
    writer = csv.writer(csv_file, delimiter=';')
    writer.writerow('my_utf8_string')

Informationen zu Python 2.x finden Sie hier .

Zanon
quelle
1
Was ist, wenn der Inhalt writerowkein utf-8 ist? wird es funktionieren?
CKM
1
Keine Notwendigkeit für Pip-Installationen von Drittanbietern.
Vaibhav Vishal
3

Für mich hat die UnicodeWriterKlasse aus der Python 2 CSV-Moduldokumentation nicht wirklich funktioniert, da sie das brichtcsv.writer.write_row() Schnittstelle beschädigt.

Beispielsweise:

csv_writer = csv.writer(csv_file)
row = ['The meaning', 42]
csv_writer.writerow(row)

funktioniert, während:

csv_writer = UnicodeWriter(csv_file)
row = ['The meaning', 42]
csv_writer.writerow(row)

wird werfen AttributeError: 'int' object has no attribute 'encode'.

Da UnicodeWriteroffensichtlich erwartet wird, dass alle Spaltenwerte Zeichenfolgen sind, können wir die Werte selbst konvertieren und einfach das Standard-CSV-Modul verwenden:

def to_utf8(lst):
    return [unicode(elem).encode('utf-8') for elem in lst]

...
csv_writer.writerow(to_utf8(row))

Oder wir können sogar csv_writer mit einem Affen-Patch versehen, um eine write_utf8_rowFunktion hinzuzufügen - die Übung bleibt dem Leser überlassen.

Bojan Bogdanovic
quelle
2

Die Beispiele in der Python-Dokumentation zeigen, wie Unicode-CSV-Dateien geschrieben werden: http://docs.python.org/2/library/csv.html#examples

(Der Code kann hier nicht kopiert werden, da er urheberrechtlich geschützt ist.)

Aaron Digulla
quelle
1
Danke für den Link. Es war hilfreich. Meines Wissens können Sie den Code hier nicht einfügen, auch wenn Sie den Link gepostet haben. (+1 für den Besitz des Urheberrechts)
Mutant
1
@ Mutant: Code ist nicht wie wissenschaftliche Arbeiten. Der Code ist urheberrechtlich geschützt. Obwohl ich zu 99,999% sicher bin, dass die Python-Besitzer SO nicht wegen des Kopierens ihres Codes verklagen würden, hatte ich keine Lust, ihre lange Lizenz zu lesen , um herauszufinden, ob dies zulässig ist oder nicht. Es ist auch gut, ab und zu daran zu erinnern, dass "ich es auf meinem Monitor sehen kann"! = "Ich kann damit machen, was ich will" :-)
Aaron Digulla
1
Danke für die Erinnerung. Leider wurde die Welt, in der wir leben, so (unangemessen) schnell und nachlässig, dass Informationen schneller fließen, als man sich vorstellen kann. Sie müssen immer wieder daran erinnert werden, welche Einschränkung wichtig ist. Danke dafür :)
Mutant
2
Der Link zu docs ist halb nützlich (Beispiele sind besser), aber das Argument "copyright" hier ist übertrieben und albern. Python ist explizit Open Source ( v2 v3 ). Die Lizenz ist klar: "Lizenzfreie, weltweite Lizenz zum Reproduzieren, Analysieren, Testen, Aufführen und / oder öffentlichen Anzeigen, Vorbereiten abgeleiteter Werke, Verteilen ... [usw. usw.]" Sogar der einfache Satz im oben auf der Seite sollte "GPL-kompatibel" Ihnen Komfort bieten. Teilen Sie Open Source-Inhalte. Ändern Sie es sogar, wenn Sie möchten. Es ist aus einem bestimmten Grund Open Source.
Alttag
@alttag Das Kopieren oder Verwenden von GPLd-Code in einem Projekt bedeutet, dass sich der gesamte andere Code im selben Projekt jetzt auch unter der GPL befindet. Da ich kein Anwalt für Urheberrecht bin, weiß ich nicht, was dies in Bezug auf den auf einer Website veröffentlichten Code bedeutet.
Aaron Digulla
0

Für python2 können Sie diesen Code verwenden, bevor csv_writer.writerows(rows)
Dieser Code KEINE Ganzzahlen in utf-8-Zeichenfolgen konvertiert

def encode_rows_to_utf8 (Zeilen):
    encoded_rows = []
    für Reihe in Reihe:
        encoded_row = []
        für Wert in Zeile:
            if isinstance (Wert, Basisstring):
                value = Unicode (Wert) .encode ("utf-8")
            encoded_row.append (Wert)
        encoded_rows.append (encoded_row)
    return encoded_rows
Pymen
quelle
-1

Ein sehr einfacher Hack ist die Verwendung des JSON-Imports anstelle von CSV. Führen Sie beispielsweise anstelle von csv.writer Folgendes aus:

    fd = codecs.open(tempfilename, 'wb', 'utf-8')  
    for c in whatever :
        fd.write( json.dumps(c) [1:-1] )   # json dumps writes ["a",..]
        fd.write('\n')
    fd.close()

Grundsätzlich ist die json-formatierte Zeichenfolge angesichts der Liste der Felder in der richtigen Reihenfolge identisch mit einer CSV-Zeile, mit Ausnahme von [und] am Anfang bzw. Ende. Und json scheint in Python 2 gegenüber utf-8 robust zu sein. *

vpathak
quelle