Seite 1 von 1

Encoding-Namen und ihre Kurzformen...

Verfasst: Freitag 10. Februar 2012, 10:23
von mutetella
Hallo,

weiß jemand, woher die Encoding-Namen und ihre Aliase (was für ein Wort... :shock: ) in Python stammen?

Mir geht es darum, ob Vergleiche wie

Code: Alles auswählen

>>> sys.stdout.encoding == 'UTF-8'
auch mal in die Hose gehen können, wenn dort statt 'UTF-8' vielleicht auch mal ein 'UTF8' stehen könnte...?
Bei 'ISO-8859-1' ist das ja noch verworrener, kann ich ja als Parameter sowohl 'iso8859', 'latin1', 'iso-8859-1' ... angeben.

Wird also bei Rückgaben von encoding-Namen immer die gesamte Form ('UTF-8', 'ISO-8859-1', 'CP-1252') verwendet (die ich so weder im Python '/encodings'-Verzeichnis noch in der dortigen 'aliases.py' finden konnte)?

mutetella

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Freitag 10. Februar 2012, 18:37
von problembär
Erster Gedanke war, man könnte vielleicht folgendes machen:

Code: Alles auswählen

if sys.stdout.encoding in ('ISO-8859-1', 'iso-8859-1', 'iso8859', 'latin1'):
    pass
;)

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Freitag 10. Februar 2012, 19:18
von Andev
Hallo,

üblicherweise wird der Codec-Name zurückgegeben, darauf verlassen würde ich mich aber nicht, nicht zuletzt da der encoding-Wert beliebig verändert werden kann. Eine einfache Methode zum Überprüfen ist mir nicht bekannt, vielleicht kennt die ja jemand anders.
Eines aber: Der Bindestrich '-' wird automatisch als Alias für '_' gewertet. 'utf-8' ist also nichts anders als ein Alias für 'utf_8' und wird nicht explizit in den Tabellen aufgelistet.

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Freitag 10. Februar 2012, 19:29
von lunar
@mutetella: Über das "codecs" Modul erhältst Du den kanonischen Namen einer Textkodierung:

Code: Alles auswählen

In [4]: codecs.lookup('iso8859-1').name
Out[4]: 'iso8859-1'

In [5]: codecs.lookup('iso 8859-1').name
Out[5]: 'iso8859-1'

In [6]: codecs.lookup('latin1').name
Out[6]: 'iso8859-1'

In [7]: codecs.lookup('ISO 8859-1').name
Out[7]: 'iso8859-1'

In [8]: codecs.lookup('utf-8').name
Out[8]: 'utf-8'

In [9]: codecs.lookup('utf8').name
Out[9]: 'utf-8'
Auf den exakten kanonischen Namen würde ich mich nicht verlassen, aber Du kannst das "CodecInfo"-Objekt für einen bekannten Codec holen, und dessen Name dann mit dem CodecInfo-Objekt für die zu prüfende Kodierung vergleichen, beispielsweise "codecs.lookup(sys.stdout.encoding).name == codecs.lookup('utf-8').name".

Ich sehe allerdings gerade nicht, wozu man sowas brauchen könnte...

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Freitag 10. Februar 2012, 23:18
von mutetella
lunar hat geschrieben:Ich sehe allerdings gerade nicht, wozu man sowas brauchen könnte...
Wenn ich einen Tastendruck vom Terminal einlese, hängt es vom encoding des Terminals ab, ob ich z. B. für das 'ä' ein '\xe4' (LATIN1) oder ein '\xc3\xa4' erhalte. Wenn ich die Bytes dann übersetze kann das '\xe4' als Start einer 3-byte Sequenz (UTF-8) oder als 'ä' (LATIN1) interpretiert werden, das '\xc3' als Start einer 2-byte Sequenz (UTF-8) oder als 'Ã' (LATIN1).
Jetzt könnte man natürlich die Sequenzen anhand der folgenden Bytes, die zwischen '\x80' und '\xbf' liegen müssen, identifizieren.
Könnte man... wenn allerdings das encoding feststeht, kann ich bei ISO's (und anderen encodings, die 'nur' mit 1 Byte auskommen) die Sequenzerkennung und -übersetzung überspringen und das Byte gleich weiterverwenden.

mutetella

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 10:52
von lunar
@mutetella: Ich sehe immer noch nicht, warum man da jetzt die Kodierung prüfen sollte. Du kannst doch einfach alle Bytes lesen und dann einfach mit der Kodierung dekodieren. Ich glaube, Du versuchst hier wieder mal ein XY-Problem zu lösen...

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 12:37
von sma
Ein Bytestring vom System kann doch einfach mit decode() in einen richtigen (Unicode) String konvertiert werden. Ohne Argument benutzt decode() das Encoding des Systems. Da muss man doch nicht mit hart-verdrahteten Namen arbeiten?!

Stefan

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 12:48
von BlackJack
@sma: Ohne Argument benutzt `decode()` bei mir ASCII und nicht die Kodierung des Systems. So eine Kodierung gibt es ja auch gar nicht.

Code: Alles auswählen

In [55]: 'hällö'.decode()
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 12:54
von mutetella
@sma + lunar:
Grundsätzlich ja, wenn die Umgebung 'sauber' ist. Das von mir beschriebene Szenario tritt dann auf, wenn das Terminal ein anderes encoding als das Systemencoding verwendet, z. B. ein xterm, das mit der Option '-en iso88591' aus einer 'utf-8'-Umgebung heraus gestartet wird. Wenn ich hier 'sys.stdout.encoding' abfrage, erhalte ich 'UTF-8', das ausgelesene/die ausgelesenen Byte(s) müssen allerdings 'iso8859-1'-decodiert werden.

Das Problem lässt sich am einfachsten umgehen, wenn ich nicht 'sys.stdout.encoding' sondern das jeweilige encoding des Terminals abfrage. Eine Möglichkeit, an diese Information zu kommen, suche ich gerade (bin da für Hinweise sehr empfänglich... ;-) ).

mutetella

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 13:03
von DasIch
Wenn sys.stdout.encoding nicht dem Encoding des Terminals entspricht, hat entweder deine Python Implementation einen Bug, das Terminal einen Bug oder das System ist falsch konfiguriert. Irgendwelche abenteuerlichen Workarounds die wahrscheinlich ohnehin nicht wirklich funktionieren dürften da wohl kaum eine adequate Lösung sein.

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 13:35
von mutetella
@DasIch:
Ganz so einfach ist es leider nicht... ein zerschossenes System oder ein Bug wäre mir natürlich auch am liebsten... ;-)

Python übernimmt das encoding aus 'LANG'. Und 'LANG' gibt keine Auskunft darüber, welches encoding im jeweiligen Terminal gerade verwendet wird.
Anderst herum: Wenn ich in 'LANG' ein zum laufenden Terminal differentes encoding hinterlege, erhalte ich über 'sys.stdout.encoding' das encoding aus 'LANG', nicht das des Terminals.

Und dass ein Terminal auch mal unter einem anderen encoding als dem des Systems läuft ist ja keine an den Haaren herbeigezogene Möglichkeit, oder?

mutetella

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 13:40
von deets
@mutetella

Ja, natuerlich kann ich das aendern. Jederzeit. Auch wenn du gerade Ausgaben in UTF-8 machst in einer Schleife, vor der du das encoding umgestellt hast.

Mit anderen Worten: es gibt keinen 100%igen Weg. Wenn der User das encoding des Terminals zwischendurch umstellt (das Terminal selbst sollte ja die LANG-variable setzten zu Beginn der Session, wenn du die nicht selbst manipulierst) - dann ist halt Essig.

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 13:51
von DasIch
mutetella hat geschrieben:Python übernimmt das encoding aus 'LANG'. Und 'LANG' gibt keine Auskunft darüber, welches encoding im jeweiligen Terminal gerade verwendet wird.
Anderst herum: Wenn ich in 'LANG' ein zum laufenden Terminal differentes encoding hinterlege, erhalte ich über 'sys.stdout.encoding' das encoding aus 'LANG', nicht das des Terminals.
Diese sollten möglichst identisch sein, sind sie i.d.R. auch schliesslich verlässt sich jedes lokalisierte Program darauf.
Und dass ein Terminal auch mal unter einem anderen encoding als dem des Systems läuft ist ja keine an den Haaren herbeigezogene Möglichkeit, oder?
Diese Möglichkeit könnte durchaus eintreten aber im Normalfall sollte sie es nicht. Selbst wenn sie eintritt wird es deswegen nicht automatisch dein Problem, speziell dann wenn du das Problem ohnehin nicht lösen kannst, es sei den du errätst zufällig die Lösung.

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 14:09
von lunar
@mutetella: Es ist ein Bedienungsfehler des Nutzers, wenn Lokalisierungseinstellungen und Terminalkodierung nicht zusammen passen. Wenn Du in einer UTF-8-Umgebung die Terminal-Kodierung auf ISO 8859-1 umstellst, dann funktioniert kein Programm mehr korrekt.

Sowas wie die "Terminal-Kodierung" gibt es nicht in standardisierter Weise und mithin kann ein Programm sie auch nicht einfach so abfragen. Nutze "$LANG" beziehungsweise "sys.stdout.encoding", "sys.getfilesystemencoding()" und Konsorten. Wenn der Benutzer die Kodierungseinstellungen verhaut, ist das nicht Deine Schuld und im Programm Du kannst auch nichts dagegen tun.

@deets: Ich kenne kein Terminalemulator unter Linux, welcher automatisch "LANG" setzt. Der Nutzer muss schon selbst dafür sorgen, dass die Lokalisierungs- und Kodierungseinstellungen alle zusammen passen.

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 16:42
von mutetella
Ok, letztlich hab' ich ja immer noch die Möglichkeit, ein 'set_encoding()' oder sowas einzubauen, über das der Nutzer bei Bedarf das encoding ändern kann, falls Terminal und System variieren.
Mir hätte hier ein Automatismus gefallen, so eine Art 'SIGENCCH'...

Und dass andere Konsolenprogramme auch Schwierigkeiten in der Übersetzung außerhalb des Systemencodings haben versöhnt mich ein wenig, unbefriedigend bleibt es trotzdem... :(

mutetella

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 17:02
von lunar
@mutetella: Mein Gott, wie oft kommt sowas denn schon vor? Ich meine, wer kommt denn schon auf die Idee, ein Terminal absichtlich und wissentlich falsch zu konfigurieren?

Und ja, Terminualemulator sind unbefriedigend... aber eben auch schon steinalt, und vor 40 Jahren waren Textkodierung noch ein ziemlich überschaubares Thema.

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 17:39
von mutetella
@lunar: Beim gnome-terminal kann ich mit 3 Klicks eine andere Zeichenkodierung einstellen. Jedem anderen mir bekannten Terminal kann ich über eine Option die Kodierung mitgeben.
Ich würde also nicht von einem 'absichtlich und wissentlich falsch' konfiguriertem Terminal sondern von einem Feature sprechen, das (x)terms nunmal bieten und von den darin laufenden Programmen auch berücksichtigt werden sollte.

Und ich vermute mal, dass das Problem weniger von den Terminals als vielmehr von der Unmöglichkeit, stdout/stdin zu separieren, verursacht wird. Aber diese Vermutung kann auch ein zum Himmel stinkender Blödsinn sein, das weiß ich nicht... :K

mutetella

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 17:49
von BlackJack
@mutetella: Programme können die Kodierung des Terminals aber nicht berücksichtigen, da es ja wohl keinen standardisierten Weg gibt, an diese Information heran zu kommen.

Die Einstellungsmöglichkeit in Terminals ist für Programme gedacht, die sich nicht um LANG oder LC_LANG kümmern und einfach Stur mit ihrer fest eingebauten Kodierung operieren. Wenn man daran rum schraubt ohne dass man so ein Programm starten will und LANG/LC_ALL nicht auch passend setzt, dann konfiguriert man das Terminal absichtlich falsch! Vielleicht unwissentlich, aber falsch bleibt es trotzdem.

Re: Encoding-Namen und ihre Kurzformen...

Verfasst: Samstag 11. Februar 2012, 18:08
von lunar
@mutetella: Es gibt ja auch triftige Gründe, die Kodierung eines Terminals zu ändern. Beispielsweise bei einer SSH-Verbindung zu einem Server, bei dem eine andere Kodierung in $LANG eingestellt ist. Oder bei einer seriellen Verbindung zu einem embedded-System, dass eine hart kodierte Text-Kodierung verwendet.

Wenn man allerdings die Kodierung für die lokale Shell verändert, ohne deren Lokalisierungseinstellungen anzupassen, dann konfiguriert man das Terminal falsch. Und da man kaum aus Versehen im Kodierungsdialog des Terminals landet, geschieht das auch wissentlich und absichtlich. Klar kann das mal passieren, wenn man beispielsweise nach dem Schließen der SSH-Verbindung vergisst, die Kodierung zurückzusetzen, aber dann man selbst Schuld. Nicht das Programm, welches dann merkwürdige Zeichen anzeigt...

Schuld ist das Programm aber, wenn es merkwürdige Zeichen anzeigt, weil es versucht, schlauer zu sein als der Nutzer und die Text-Kodierung auf magische Weise erraten will.