Textcodierung

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
unique24
User
Beiträge: 65
Registriert: Donnerstag 5. Juli 2018, 14:51

Hallo,

ich habe immer wieder das Problem, das ein auf Linux Ubuntu laufender Code Probleme mit der Codierung hat.
Wir haben im deutschen ja öäü....
Und diese werfen an verschiedenen Stellen immer wieder eine Exception.

Beispiel:

Code: Alles auswählen

txt_filename = 'AS_%s.txt' % (code)
        buffer = cStringIO.StringIO()
        buf = codecs.getwriter("cp1252")(buffer)
        #buf=StringIO.StringIO() # io.BytesIO()
        buf.write('[%s] %s' % (self.default_code, self.name))
        buf.write('\n\n')
        buf.write(self.description_sale)
        buf.write('\n\n')
        buf.write(cleanhtml(self.description_long))
        buf.write('\n\n')
        for line in self.technical_data_line_ids:
            buf.write(line.technical_data_id.name)
            buf.write('\n')
            for val in line.value_ids:
                buf.write('  %s: %s' % (val.value_id.name, val.name))
                buf.write('\n')
        buf.write('\n\n')
        buf.write('Hersteller: ')
        buf.write('\n\n')
        buf.write('Artikelnummer: %s' % self.default_code)
        buf.seek(0)
        ftp.storbinary("STOR "+txt_filename, buf)
Bei Zeile "buf.write(' %s: %s' % (val.value_id.name, val.name))" erhalte ich:

UnicodeEncodeError: 'charmap' codec can't encode character u'\u03a6' in position 27: character maps to <undefined>

Die Daten kommen von einer Postgres Datenbank und werden über FTP auf einen Server gespeichert.

Wie muss man eine Python Klasse definieren, damit der Zeichensatz für Deutsch paßt?

Danke!
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist halt kein Deutsch. Du gibts die deutsche codepage an, aber der Fehler sagt, dass du dann ein großes griechisches Phi speichern willst. https://www.fileformat.info/info/unicod ... /index.htm

Wenn du nicht sicherstellen kannst, dass deine Daten nur deutsche Umlaute (und was sonst in cp1252 ist) enthalten, dann kannst du die nur in einem umfassenderen encoding wie UTF8 ablegen oder musst sie ausfiltern.
unique24
User
Beiträge: 65
Registriert: Donnerstag 5. Juli 2018, 14:51

Hallo und vielen Dank!

Nun, gerne kann alles UTF-8 sein .. solange ich eben als File den korrekten Inhalt bekomme.
Es wäre sehr nett, wenn du mir sagen könntest, wie ich alles auf UTF-8 einstelle.

Vor allem der FTP Upload zickt immer.
unique24
User
Beiträge: 65
Registriert: Donnerstag 5. Juli 2018, 14:51

Nochmals Hallo!

Also wenn ich am beginn des Codes folgendes einfüge:

Code: Alles auswählen

import sys  

reload(sys)  
sys.setdefaultencoding('utf8')
aber wenn ich dann die Textdatei öffne, sind die Zeichen eben nicht richtig :-(
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Dass `setdefaultencoding` in sys nicht existiert ist Absicht. Da irgendwie herumzumogeln, ist nicht gut. Dieser Codeabschnitt kommt immer wieder, aber er löst kein Problem.

Bei Deinem getwriter mußt Du doch einfach nur "utf8" eintragen
unique24
User
Beiträge: 65
Registriert: Donnerstag 5. Juli 2018, 14:51

Ich habe gerade gesehen, das auch in "UTF-8" ein Textfile, welches man im Browser öffnet, nicht richtig dargestellt wird.
Setze ich mit einem Texteditor das File auf "UTF-8 BOM" .. dann wird alles richtig angezeigt.

Darf ich nochmal um Hilfe bitten?
unique24
User
Beiträge: 65
Registriert: Donnerstag 5. Juli 2018, 14:51

Habs hinbekommen "utf-8-sig"

Danke!
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei ich das nicht machen würde. UTF-8 mit BOM ist nervig. Wenn der Browser das falsch darstellt ist das ein Problem das man beim Browser lösen sollte beziehungsweise halt Textdateien nicht im Browser öffnen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
DeaD_EyE
User
Beiträge: 1017
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Nimm UTF-8 ohne BOM und am besten Python 2.7 gleich entfernen und Python 3.7 installieren.
Der Browser bekommt eigentlich die Zeichenkodierung von einem Webserver mitgeteilt.
Einmal steht die Kodierung meistens im Header und als Meta-Tag steht es dann meist auch nochmal im HTML-Dokument.
Eine lokale Textdatei einfach im Webbrowser zu öffnen, kann zu einer falschen Erkennung des Zeichensatzes führen.

Um vielen Problem aus dem Weg zu gehen, macht man am besten alles in UTF-8.
Bei Python 3 ist der Unicode Support besser. Es gibt auch öfters mal Updates des Unicode-Standards.
Python 3.7 unterstützt die Unicode-Version 11.0.

Python 2.7.15 unterstützt die Version 5.2.0 des Standards, also auch kein kotzendes Smiley.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@unique24: woher kommt denn das File im Browser? Über einen Server, der den Content-Type falsch setzt oder als lokale Datei, wo die Defaults falsch gesetzt sind? utf8 mit BOM gibt es eigentlich nicht, weil das BOM nur dazu da ist, die Endiness bei 16 oder 32 bit Zeichenkodierung festzulegen.

@DeaD_EyE: es kann verschiedene Gründe geben bei Python2.7 zu bleiben. Prinzipiell sollte das alles ja auch mit Python2.7 funktionieren. Das Problem ist hier ja der Browser. Die Unicode-Version spielt auch nur bei Spezialanwendungen eine Rolle. Für einfache Textverarbeitung ist die egal.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1017
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

@Sirius: Ja, das wird auch mit Python 2.7 funktionieren, wenn man es richtig macht und keine Unicode vorkommt, der im Unicode-Standard 5.2.0 nicht definiert ist.
Der Knackpunkt ist, dass man keine Unterscheidung zwischen strings und bytes hat.

Mein absolutes Killerargument, wieso man frühzeitig auf Python 3 wechseln sollte: https://pythonclock.org/
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@DeaD_EyE: man hat sehr wohl eine Unterscheidung zwischen Unicode-Strings und Byte-Strings. Die Unicode-Standards geben nur weiteren Zeichen eine Bedeutung, arbeiten kann man aber mit den 1Mio Zeichen, die seit Unicode 2.0 definierbar sind, problemlos. Ich werde wahrscheinlich weit über 2020 hinaus mit Python 2.7 arbeiten und werde trotzdem nicht daran sterben.
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Also ich sehe auch noch nicht das Python 2.7 pünktlich am Stichtag in den Ruhestand geht. Dazu gibt es einfach zu viel Code da draussen der in 2.7 geschrieben und noch nicht portiert ist. Solange nach dem Datum keine fiesen Sicherheitslücken aufgedeckt werden, gibt es auch keinen direkten Druck zügig umzustellen.

Dieser Countdown ist auch alles andere als ein Killerargument. Interessanter dürften da eher die externen Bibliotheken sein, die den 2.7-Support einstellen. Denn bisher gibt es in der 3er-Version bei Python selbst für mich keinen Grund das unbedingt haben zu wollen. Das ist gefühlt eher ein, na dann muss ich das wohl machen und ausser Arbeit und Fehlern die bei der Portierung passieren werden, habe ich da nix von. Neue Features oder Bugfixes in Bibliotheken die ich für Projekte verwende, werden sicher wesentlich stärkere Faktoren für einen Umstieg für mich sein. Also Pluspunkte die den Unicode-Scheiss, den immer stärkeren Druck zur ”statischen” Typisierung und „wir wollen ja gar nicht unbedingt POSIX wenn es anders für Anfänger einfacher ist“ ausgleichen.

@unique24: Vor dem Hintergrund einer eventuellen Portierung: Ich würde bei 2.7 aber schon dazu raten ein wenig ”zukunftsorientiert” zu programmieren, also Beispielsweise `io.BytesIO` und `io.TextIOWrapper` statt `cStringIO.StringIO` und `codecs.getwriter()` zu verwenden.

Es sieht auch so aus als wenn Du von einer Templating-Bibliothek profitieren könntest.

Um so mehr wenn Du wirklich sicher sein willst, das der Leser die richtigen Zeichen für Umlaute & Co angezeigt bekommen soll, denn in dem Fall darfst Du einfach keine Textdatei verwenden, sondern musst auf ein Format umsteigen das neben dem kodierten Text auch die Information mit speichert *wie* er denn kodiert ist. HTML ist da wohl das einfachste und sehr verbreitete Format. Das wird dann auch im Browser garantiert richtig angezeigt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten