[mailinglist] Re: [Python-de] htmllib und Umlaute

"Martin v. Löwis" martin at v.loewis.de
Thu May 1 17:43:21 EDT 2003


Klaus Meyer wrote:

> Es sind Bytestrings, solange die Filenamen oder Tex im Entry ohne 
> Umlaute sind, sonst sind es Unicode-Strings.
> Vermutlich ist das Verhalten so "richtig"?

Es ist zumindest Absicht: Hätte Python 2.0 stets und immer 
Unicode-Objekte aus Tcl zurück gegeben, wäre zuhauf Tkinter-Code
kaputt gegangen.

Deshalb gibt es die Regel: Wenn das Ergebnis ASCII ist, wird ein
Bytestring zurück gegeben. Ansonsten, wenn das Ergebnis ein "korrekter" 
nicht-ASCII-String ist (also inten in Tcl UTF-8-kodiert), wird ein
Unicode-String zurückgegeben. Ansonsten (nicht-ASCII nicht-UTF-8) wird 
ein Bytestring zurück gegeben.

Weil Python 2.0 das so gemacht hat, muss es aus Rückwärtskompatibilität 
so bleiben. Allerdings wird Python 2.3 vermutlich öfter Unicode 
zurückgeben, nämlich immer, wenn Tcl einen richtigen String zurückgibt
(und nicht lediglich ein Objekt, das eine Stringrepräsentation hat).
Richtige Strings werden in Tcl 8.4 allerdings selten verwendet.

> Beim umgekehrten Weg, Ausgabe mit insert() in Widgets wie Entry oder 
> Text, habe bisher noch keine Unicode-Errors gesehen, obwohl doch zB 
> Print schnell einen Unicode-Error wirft. Hm, das Verhalten von Tkinter 
> bleibt hier etwas unklar. Es scheint mir ein Latin-1-Default zu geben 
> für Bytestrings mit darin enthaltenen Zeichen > 127.

Tkinter gibt Byte-Strings als Byte-String und Unicode-Strings als 
Unicode-Strings an Tcl weiter. Tcl seinerseits interpretiert 
Byte-Strings in Abhängigkeit von der Tcl-Version, das ist auch bei Tcl 
undokumentiert. Es geht ungefähr so: Wenn der String aussieht wie UTF-8, 
ist es UTF-8, ansonsten ist es die Plattform-Kodierung ("encoding 
system"). Das ist fatal, wenn man Unicode-Strings und 
nicht-ASCII-Bytestrings in einem Entry-Feld mischt: dann erhält man 
einen String mit gemischter Kodierung.

Dieses Problem vermeidet man am besten, indem man immer Unicode-Strings, 
oder höchstens ASCII-Byte-Strings an Tcl übergibt.

> Zur Erzeugung von Unicode-Strings gibt es zB die folgenden 2 Methoden:
> 
> unicode("String", "encode")
> u"String"
> 
> Im ersten Fall kann man einen Encoder angeben

Was man hier angibt ist ein *Dekoder*.

decode: bytestring->unicodestring
encode: unicodestring->bytestring

> aber nach welchem System 
> wird eigentlich bei u"" encodet? Hier muss doch ein Default wirken?

Gar nicht. unicode(u) ist idempotent (wie auch str(s), int(i) usw.)
unicode(u, "codec") ist falsch.

Deshalb kann man bei Tkinter-String-Ergebnissen immer

   r = unicode(r)

schreiben: Ist es ein Byte-String, so ist er ASCII-kodiert, und 
unicode(r) konvertiert ihn korrekt (sofern das system default encoding 
nicht geändert wurde); ist es ein Unicode-String, so macht unicode(r) 
gar nichts.

Ciao,
Martin






More information about the Python-de mailing list