Ich habe ein seltsames Verhalten, wenn ich die locale
-Bibliothek mit Unicode-Eingabe verwende. Im Folgenden finden Sie ein funktionierendes Beispiel:
Ich habe das auf Python 3.3, 3.4 und 3.5 gesehen. Ich bekomme keine Fehlermeldung auf Python 2.7.
Soweit ich sehen kann, liegt meine Unicode-Eingabe innerhalb des entsprechenden Unicode-Bereichs, so dass es aussieht, als ob etwas internes zu strxfrm
bei Verwendung der 'en_US.UTF-8' die Eingabe außerhalb des Bereichs bewegt.
Ich verwende Mac OS X und dieses Verhalten könnte mit Ссылка zusammenhängen ... aber ich hatte den Eindruck, dass dies der Fall ist Fehler würden sich nur als falsche Ergebnisse manifestieren, nicht als Ausnahme. Ich kann auf meinem SLES 11-Computer nicht replizieren, und andere bestätigen, dass sie nicht auf Ubuntu, Centos oder Windows replizieren können. Es kann aufschlussreich sein, in den Kommentaren von anderen Betriebssystemen zu hören.
Kann jemand erklären, was hier unter der Haube passiert?
In Python 3.x wird intern die Funktion locale.strxfrm(s)
verwendet die POSIX C-Funktion wcsxfrm () , die auf der aktuellen LC_COLLATE-Einstellung basiert. Der POSIX-Standard definiert die Transformation auf diese Weise:
Die Transformation muss so aussehen, dass
wcscmp()
auf zwei angewendet wird transformierte breite Strings, es soll einen Wert größer als, gleich zurückgeben bis oder weniger als 0, entsprechend dem Ergebnis vonwcscoll()
angewendet zu den gleichen zwei ursprünglichen breiten Zeichenketten.
Diese Definition kann auf mehrere Arten implementiert werden und erfordert nicht einmal, dass die resultierende Zeichenfolge lesbar ist.
Ich habe ein kleines C-Codebeispiel erstellt, um zu demonstrieren, wie es funktioniert:
%Vor%Es druckt die Zeichenfolge vor und nach der Umwandlung.
Unter Linux (Debian Jessie) ist dies das Ergebnis:
%Vor%Beim Ausführen unter OSX (10.11.1) lautet das Ergebnis:
%Vor% Sie können sehen, dass die Ausgabe von wcsxfrm()
auf OSX das Zeichen U + 110000 enthält, das in einer Python-Zeichenfolge nicht zulässig ist. Dies ist also die Fehlerquelle.
In Python 2.7 wird der Fehler nicht ausgelöst, da locale.strxfrm()
Die Implementierung basiert auf strxfrm()
C-Funktion.
UPDATE:
Wenn ich weiter nachdenke, sehe ich, dass die LC_COLLATE-Definition für en_US.UTF-8 auf OSX eine Verbindung zur Definition von la_LN.US-ASCII ist.
%Vor% Ich fand die tatsächliche Definition in den Quellen von Apple. Der Inhalt der Datei la_LN.US-ASCII.src
ist der folgende:
2. UPDATE:
Ich habe die Funktion wcsxfrm()
auf OSX weiter getestet. Bei Verwendung der La_LN.US-ASCII-Sortierung, die eine Folge von Wide-Zeichen C1..Cn
als Eingabe enthält, ist die Ausgabe eine Zeichenkette mit der folgenden Form:
wo
%Vor% Mit diesem Algorithmus wird \x10fefd
zu 0x103 0x1 0x110000
Ich habe überprüft, dass jedes UTF-8-Gebietsschema diese Sortierung unter OSX verwendet. Daher möchte ich sagen, dass die Unterstützung für die Unterstützung von UTF-8 auf Apple-Systemen unterbrochen ist. Die resultierende Reihenfolge ist fast die gleiche, die man beim normalen Bytevergleich erhält, mit dem Vorteil, dass man illegale Unicode-Zeichen erhalten kann.
Tags und Links python locale unicode python-3.x