Unicode in csv speichern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
KlausS
User
Beiträge: 40
Registriert: Donnerstag 24. Januar 2008, 08:52
Wohnort: Leverkusen

Hallo Liste,

ich muss mich mal wieder mit Python beschäftigen, aber im Moment finde ich trotz längerer Suche keinen richtigen Ansatz für mein Problem. Ich lese mit Python 2.6.5 Daten aus einer Filegeodatabase von ArcGIS aus. Die meisten Felder enthalten Text vom Type 'unicode'. Teile der Daten muss ich in einer csv-Datei speichern. Das wollte ich mit dem csv.writer erledigen. Da aber auch Umlaute in den Texten enthalten sind, komme ich da nicht weiter.
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 1: ordinal not in range(128)
Kann mir jemand mal einen Wink mit dem Zaunpfahl, ob es mit csv.writer geht oder wo ich für die Funktion suchen muss.

Danke

Klaus
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Das CSV-Modul ist leider in Sachen Unicode imho verbuggt. Wie ich grad sehe, hat Dir derdon bereits die Lösun gepostet ;-)

Dennoch erlaube ich mir darauf hinzuweisen, dass Du niemals Unicode in eine Datei speicherst, sondern ein spezielles Encoding-Format, welches u.U. die kompletten Codepoints von Unicode darstellen kann. UTF-8 ist da z.B. ein beliebter Kandidat.

Wenn Du sagst "die meisten Felder" enthielten Unicode, so solltest Du sicherstellen, dass die anderen tatsächlich nur ASCII-Codes enthalten. Dann bekommst Du bei der Umwandlung in UTF-8 (encode) keine Probleme. Sinnvoller ist es allerdings eigentlich, alle Daten möglichst schnell nach einer Eingabeoperation in Unicode-Objekte zu wandeln (decode) und intern nur mit Unicode zu arbeiten. Allerdings weiß ich nicht, ob Du die Objekte da beeinflussen kannst.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
KlausS
User
Beiträge: 40
Registriert: Donnerstag 24. Januar 2008, 08:52
Wohnort: Leverkusen

@Hyperion:

Da auch Interger und Datumswerte in dem Datensatz stehen, habe ich versucht, dass wie folgt zu lösen:

Code: Alles auswählen

if type(wert) == 'unicode':
    wert = wert.encode('utf-8')
Aber beim Schreiben kommt dann der beschriebene Fehler. Ist das Encoding so falsch? Wenn es denn funktionieren würde, käme dann in der .csv eine sinnvolle Darstellung heraus oder müsste man dann Latin-1 wählen?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

KlausS hat geschrieben:@Hyperion:

Da auch Interger und Datumswerte in dem Datensatz stehen, habe ich versucht, dass wie folgt zu lösen:

Code: Alles auswählen

if type(wert) == 'unicode':
    wert = wert.encode('utf-8')
Aber beim Schreiben kommt dann der beschriebene Fehler.
Der "Fehler" ist ein Fehler im CSV-Modul, welchen Du umgehen kannst. Dazu gibt es doch unter den Beispielen komplette Implementiereungen für utf-8-writer und reader.

Aller Felder, in denen normale ASCII-Zeichen vorkommen sollten dann keine Probleme mehr bereiten, da eine Wandlung nach Unicode out of the box funktioniert. Damit schließlich hat dann auch ein UTF-8-Writer keine Probleme mehr.

Typen prüft man mit `isinstance`:

Code: Alles auswählen

In [1]: isinstance(u"Hallo", unicode)
Out[1]: True

In [2]: isinstance(u"Hallo", str)
Out[2]: False
Evtl. liest Du Dir mal die Quellen in meiner Signatur durch? Du scheinst noch kein Verständnis für den Unterschied Unicode / Bytestring zu haben - das fiel mir damals auch schwer. Unicode != UTF-8!!! UTF-8 ist auch nur eine Bytestring-Kodierung.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
KlausS
User
Beiträge: 40
Registriert: Donnerstag 24. Januar 2008, 08:52
Wohnort: Leverkusen

@Hyperion:
Die Quellen zu deiner Signatur hatte ich mir schon durchgelesen. Das eigentliche Problem war die falsche Typenprüfung. Ich habe dadurch nicht bemerkt, dass das Encoding gar nicht läuft. :oops: Ich hoffe, das ich in nächster Zeit wieder mehr mit Python arbeiten kann, um ein wenig Routine zu bekommen. Aber die Probleme mit den Umlauten sind für mich ziemlich schwierig nachzuvollziehen.

Danke für deine Unterstützung

Klaus
Antworten