Umlaute, Linux und IDLE / Eric: noch mehr Seltsamkeiten

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
bb1898
User
Beiträge: 200
Registriert: Mittwoch 12. Juli 2006, 14:28

"Noch mehr": nach meinem besten Wissen und Gewissen hier im Forum so noch nicht dran gewesen. Wenn doch, habe ich dumm gesucht und bitte um Nachhilfe.

Alle Versuche unter SUSE Linux 10.0, zentral auf UTF-8 eingestellt.

1. Eric (habe die Version jetzt nicht greifbar, dürfte 3.8.xxx sein), im interaktiven Fenster:

Code: Alles auswählen

st = 'Münster'
Also ein gewöhnlicher Bytestring. Das Encoding bringe ich bisher nicht raus, weil Eric mir bei sys.stdout.encoding einen AttributeError an den Kopf wirft.

Code: Alles auswählen

print st    # ok, keine Fehlermeldung, das ü sieht richtig aus (wenn auch blässlich).
Jetzt soll daraus Unicode werden:

Code: Alles auswählen

st_latin = st.decode('latin-1')
Keine Fehlermeldung, Ausgabe mit print wieder ok.

Code: Alles auswählen

st_utf = st.decode('utf-8')
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 1-6: unsupported unicode code range.

Das kommt mir merkwürdig vor. Wenn ich es richtig interpretiere, heißt es doch, dass im Bereich 128-255 Werte vorkommen, denen in utf-8 kein Zeichen entspricht. Wieso denn das? Andere Werte als 'ü' würden mich ja nicht wundern.

2. IDLE:

sys.stdout.encoding ist 'utf-8'. Der obige Versuch ergibt bei st_utf einen String, der mit print richtig als 'Münster' ausgegeben wird, bei st_latin werden für das 'ü' zwei Zeichen ausgegeben. So weit ok.

Jetzt das Umgekehrte:

Code: Alles auswählen

uu = u'Köln'
s_utf = uu.encode('utf-8')
s_latin = uu.encode('latin-1')
Jetzt wird s_utf mit print fehlerhaft ausgegeben, s_latin dagegen richtig. Erwartet hätte ich genau das Umgekehrte.

Unter Windows (dort sys.stdout.encoding = 'cp1252') alles wie erwartet.

Kann mir jemand auf die Sprünge helfen?
BlackJack

bb1898 hat geschrieben:Alle Versuche unter SUSE Linux 10.0, zentral auf UTF-8 eingestellt.

1. Eric (habe die Version jetzt nicht greifbar, dürfte 3.8.xxx sein), im interaktiven Fenster:

Code: Alles auswählen

st = 'Münster'
Also ein gewöhnlicher Bytestring. Das Encoding bringe ich bisher nicht raus, weil Eric mir bei sys.stdout.encoding einen AttributeError an den Kopf wirft.
Wie das kodiert ist hat nichts mit `sys.*` zu tun, sondern was Eric als Einstellung benutzt.

Code: Alles auswählen

print st    # ok, keine Fehlermeldung, das ü sieht richtig aus (wenn auch blässlich).
Jetzt soll daraus Unicode werden:

Code: Alles auswählen

st_latin = st.decode('latin-1')
Keine Fehlermeldung, Ausgabe mit print wieder ok.
Was den Verdacht nahelegt, das der Quelltext in Latin-1 kodiert ist.

Code: Alles auswählen

st_utf = st.decode('utf-8')
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 1-6: unsupported unicode code range.

Das kommt mir merkwürdig vor. Wenn ich es richtig interpretiere, heißt es doch, dass im Bereich 128-255 Werte vorkommen, denen in utf-8 kein Zeichen entspricht. Wieso denn das? Andere Werte als 'ü' würden mich ja nicht wundern.
Falsch interpretiert. Ein Unicode Zeichen setzt sich in UTF-8 Kodierung aus mehreren Bytes zusammen, wenn es ausserhalb von 0-127 liegt. Aus wievielen Bytes das Zeichen besteht ist in den oberen Bits des ersten Bytes so einer Sequenz kodiert. Und 0xFC ist eine ungültige Bitkombination, das heisst damit darf so eine Sequenz gar nicht anfangen. Also gibt's einen Fehler.
2. IDLE:

sys.stdout.encoding ist 'utf-8'. Der obige Versuch ergibt bei st_utf einen String, der mit print richtig als 'Münster' ausgegeben wird, bei st_latin werden für das 'ü' zwei Zeichen ausgegeben. So weit ok.

Jetzt das Umgekehrte:

Code: Alles auswählen

uu = u'Köln'
s_utf = uu.encode('utf-8')
s_latin = uu.encode('latin-1')
Jetzt wird s_utf mit print fehlerhaft ausgegeben, s_latin dagegen richtig. Erwartet hätte ich genau das Umgekehrte.

Unter Windows (dort sys.stdout.encoding = 'cp1252') alles wie erwartet.

Kann mir jemand auf die Sprünge helfen?
Ich wüsste jetzt nicht wie. Wenn eine interaktive Umgebung Dir nicht verrät, was sie als Kodierung verwendet wenn Du Byte-Zeichenketten oder Unicode Zeichenketten eingibst, dann musst Du halt raten und/oder überrascht sein. Idle scheint zum Beispiel Latin-1 bei Eingaben zu erwarten. Wenn das System UTF-8 liefert, dann gibt das natürlich murks. Du hättest Dir das 'Köln' schon mal als Unicode Zeichenkette mit `repr()` anzeigen lassen können um das zu sehen.
bb1898
User
Beiträge: 200
Registriert: Mittwoch 12. Juli 2006, 14:28

BlackJack hat geschrieben: Falsch interpretiert. Ein Unicode Zeichen setzt sich in UTF-8 Kodierung aus mehreren Bytes zusammen, wenn es ausserhalb von 0-127 liegt. Aus wievielen Bytes das Zeichen besteht ist in den oberen Bits des ersten Bytes so einer Sequenz kodiert. Und 0xFC ist eine ungültige Bitkombination, das heisst damit darf so eine Sequenz gar nicht anfangen. Also gibt's einen Fehler.
Stimmt, ist mir inzwischen auch wieder eingefallen. Aber bei dem Versuch, das Verhalten umlautbehafteter Ortsnamen in zwei Betriebssystemen und sechserlei interaktiven Python-Fenstern zu verstehen, Quelltexte oder Dateiinhalte noch gar nicht gerechnet, drehe ich langsam durch.

Weiß vielleicht jemand, ob der Vatikan eine umfassende Liste latinisierter Ortsnamen im Web anbietet? Ich komme spätestens bei Mönchengladbach ins Schleudern.
2. IDLE:

sys.stdout.encoding ist 'utf-8'.

Code: Alles auswählen

uu = u'Köln'
s_utf = uu.encode('utf-8')
s_latin = uu.encode('latin-1')
Jetzt wird s_utf mit print fehlerhaft ausgegeben, s_latin dagegen richtig. Erwartet hätte ich genau das Umgekehrte.

Kann mir jemand auf die Sprünge helfen?
Ich wüsste jetzt nicht wie. Wenn eine interaktive Umgebung Dir nicht verrät, was sie als Kodierung verwendet wenn Du Byte-Zeichenketten oder Unicode Zeichenketten eingibst, dann musst Du halt raten und/oder überrascht sein. Idle scheint zum Beispiel Latin-1 bei Eingaben zu erwarten. Wenn das System UTF-8 liefert, dann gibt das natürlich murks. Du hättest Dir das 'Köln' schon mal als Unicode Zeichenkette mit `repr()` anzeigen lassen können um das zu sehen.
Aber diese interaktive Umgebung verrät mir doch, welche Kodierung sie verwendet:

sys.stdout.encoding = 'utf-8'

Und übrigens auch sys.stdin.encoding = 'utf-8'.

Daraus würde ich schließen, dass IDLE UTF-8 und nicht Latin-1 bei Eingaben erwartet, das scheint allerdings falsch zu sein.
BlackJack

bb1898 hat geschrieben:Aber diese interaktive Umgebung verrät mir doch, welche Kodierung sie verwendet:

sys.stdout.encoding = 'utf-8'

Und übrigens auch sys.stdin.encoding = 'utf-8'.

Daraus würde ich schließen, dass IDLE UTF-8 und nicht Latin-1 bei Eingaben erwartet, das scheint allerdings falsch zu sein.
Nein, das verrät Dir nur was Python für `stdin` und `stdout` annimmt. Über das Idle-Eingabefenster weiss Python nichts.
Antworten