Seite 1 von 1

Umlaute in Datei schreiben

Verfasst: Donnerstag 6. Dezember 2018, 08:27
von Zubi
Hallo zusammen,

ich möchte Umlaute in eine csv-Datei schreiben und wieder auslesen. Wenn ich das Programm aus Thonny (Arbeite auf Raspberry pi) starte dann funktioniert alles, wenn ich es jedoch aus dem Terminal starte kommt immer der Fehler: "ascii codec can't encode character u'\xe4' in Position 9: ordinal not in range (128)"

Ich hab jetzt schon viel recherchiert und weiß nun, dass es an der Kodierung liegt. Also habe ich schon mit dem utf-8 Schlüssel und vielen anderen Möglichkeiten herumgespielt aber bekomme es einfach nicht zum laufen.

Kann mir bitte einer ein kurzes Bsp. geben wie ich an die Sache heran gehen muss ich bin hier grad am verzweifeln. :cry:

LG Zubi

Re: Umlaute in Datei schreiben

Verfasst: Donnerstag 6. Dezember 2018, 09:49
von Sirius3
@Zubi: öffne die Datei zum Schreiben mit explizitem Encoding.
Was hast Du denn versucht. Zeige Deinen Code inklusive Fehlermeldung.

Re: Umlaute in Datei schreiben

Verfasst: Donnerstag 6. Dezember 2018, 10:18
von Zubi
Es ist ein recht langes Programm deshalb stelle ich hier mal nur den relevanten Teil ein.

Code: Alles auswählen

#-*- coding: utf-8 -*-
def new():                                          
    def quit():
        eingabeFenster.quit()
        eingabeFenster.destroy()
        
    def check():
       
        with codecs.open("Artikel.csv", "r", "utf-8") as file:      #Datei wird zum lesen geoeffnet
    
            for line in file:                       #Alle Daten in der CSV-Datei durchgehen
                
                data = line.strip().split(";")      #Daten in eine Liste umformen und an ; Trennen
                if entryNumber.get() in data or entryKoordinate.get() in data:       #ist eingegebene Artikelnummer in der Liste "data"
                    
                    vorhanden()                     #fenster mit dem hinweis dass Artikel schon vorhanden
                    eingabeFenster.quit()           #Eingabefenster wird wieder geschlossen
                    eingabeFenster.destroy()        # "
                    break
                                
        with codecs.open("Artikel.csv", "a", "utf-8") as csvfile:
            fieldnames = ["Fachkoordinate", "Artikelnummer"]
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames, delimiter=";") 
            writer.writerow({"Fachkoordinate": entryKoordinate.get(), "Artikelnummer": entryNumber.get()})
            showinfo('Hinweis', 'Artikel wurde angelegt')
Fehlermeldung:

Code: Alles auswählen

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1545, in __call__
    return self.func(*args)
  File "PbL1_0.py", line 87, in check
    writer.writerow({"Fachkoordinate": entryKoordinate.get(), "Artikelnummer": entryNumber.get()})
  File "/usr/lib/python2.7/csv.py", line 152, in writerow
    return self.writer.writerow(self._dict_to_list(rowdict))
  File "/home/pi/rpi_ws281x/python/unicodecsv/py2.py", line 86, in writerow
    _stringify_list(row, self.encoding, self.encoding_errors))
  File "/usr/lib/python2.7/codecs.py", line 706, in write
    return self.writer.write(data)
  File "/usr/lib/python2.7/codecs.py", line 369, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128)

Re: Umlaute in Datei schreiben

Verfasst: Donnerstag 6. Dezember 2018, 11:53
von Sirius3
Das ist ein bekannter Bug vom csv-Modul. Leider existieren dazu nur mehr oder weniger krude Workarounds:

Code: Alles auswählen

csv.DictWriter.writerow=lambda self, row: self.writer.writerow([f.encode('utf8') for f in self._dict_to_list(row)])
with open("Artikel.csv", "ab") as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames, delimiter=";") 
    writer.writerow({"Fachkoordinate": entryKoordinate.get(), "Artikelnummer": entryNumber.get()})
Zum Code: vermeide verschachtelte Funktionen, und die damit verbundenen quasi-globalen Variablen.
Die Funktion `check` bekommt die Variablen `entryNumber`, `entryKoordinate`, und `eingabeFenster` aus dem Nichts, das sollten Parameter der Funktion sein.
Komplexere GUI-Programme brauchen zwangsläufig Klassen-Definitionen.
Warum benutzt Du zum Lesen der csv-Datei nicht auch das csv-Modul?
Der `in`-Vergleich ist zu großzügig, da in Spalte 1 entryKoordinate und in Spalte 2 entryNumber stehen müßte, und nicht irgendwo.
Dadurch dass Du per `break´ die for-Schleife verläßt, wird das Schreiben des Datensatzes in die csv-Datei nicht unterbunden.

Re: Umlaute in Datei schreiben

Verfasst: Freitag 7. Dezember 2018, 05:26
von __blackjack__
@Zubi: Wie kommt denn der Wert `csv` bei Dir zustande? Wenn das nicht das `csv`-Modul aus der Standardbibliothek ist, sollte man das erwähnen. Wenn Du `unicodecsv` verwendest, dann gibst Du die Kodierung an der falschen Stelle an. Die Dateien müssen dann im Binärmodus geöffnet werden und die Kodierung wird bei den Writer/Reader-Objekten angegeben.