namedtuple mit Unicode-String als Name

8

Ich habe Probleme beim Zuweisen von Unicode-Strings als Namen für ein namedtuple. Das funktioniert:

%Vor%

und das nicht:

%Vor%

Ich bekomme den Fehler

%Vor%

Warum ist das der Fall? Die Dokumentation sagt, "Python 3 unterstützt auch die Verwendung von Unicode-Zeichen in Bezeichnern" und der Schlüssel ist Unicode gültig?

    
Thomas 28.05.2015, 10:12
quelle

3 Antworten

4

Das Problem liegt speziell beim Buchstaben (U + 1F79 griechischer Kleinbuchstabe Omicron mit Oxia). Dies ist ein 'Kompatibilitätszeichen': Unicode würde stattdessen lieber ό verwenden (U + 03CC griechischer Kleinbuchstabe Omicron mit Tonos). U + 1F79 existiert nur in Unicode, um zu alten Zeichensätzen zu springen, die zwischen Oxia und Tonos unterscheiden, eine Unterscheidung, die sich später als falsch herausstellte.

Wenn Sie Kompatibilitätszeichen in einem Bezeichner verwenden, normalisiert der Quellcode-Parser von Python diese automatisch zu NFKC, sodass Ihr Klassenname mit U + 03CC endet.

Leider weiß collections.namedtuple nichts darüber. Die Art, wie die neue Klasseninstanz erstellt wird, besteht darin, den gegebenen Namen in eine Menge Python-Code in einer Zeichenkette einzufügen, dann exec uting it (yuck, richtig?) Und die Klasse aus dem resultierenden locals dict mit ihrem Namen zu extrahieren. .. der ursprüngliche Name, nicht die normalisierte Version, die Python tatsächlich kompiliert hat, so dass es fehlschlägt.

Dies ist ein Fehler in collections , der sich vielleicht lohnen sollte, aber jetzt sollten Sie das kanonische Zeichen U + 03CC ό verwenden.

    
bobince 28.05.2015, 10:38
quelle
2

Das ó ist U + 1F79 ɢʀᴇᴇᴋ sᴍᴀʟʟ ʟᴇᴛᴛᴇʀ ᴏᴍɪᴄʀᴏɴ ᴡɪᴛʜ ᴏxɪᴀ. Python-Bezeichner werden wie NFKC normalisiert und U + 1F79 in NFKC wird zu U + 03CC ɢʀᴇᴇᴋ sᴍᴀʟʟ ʟᴇᴛᴛᴇʀ ᴏᴍɪᴄʀᴏɴ ᴡɪᴛʜ ᴛᴏɴᴏs.

Interessanterweise funktioniert es, wenn Sie die gleiche Zeichenfolge mit U + 1F79 verwenden, die durch U + 03CC ersetzt wurde.

%Vor%

Die Dokumentation für namedtuple behauptet, dass "Jeder gültige Python-Bezeichner für einen Feldnamen verwendet werden kann". Beide Strings sind gültige Python-Identifikatoren, die im Interpreter einfach getestet werden können.

%Vor%

Dies ist definitiv ein Fehler in der Implementierung. Ich habe es in der Implementierung von namedtuple auf dieses Bit zurückverfolgt:

%Vor%

Ich nehme an, dass der Typname, der im namespace -Wörterbuch übrig bleibt, indem er die class_definition Vorlage ausführt, die eine Python-ID ist, in NFKC-Form vorliegt und somit nicht mehr mit dem tatsächlichen Wert der typename -Variablen übereinstimmt verwendet, um es abzurufen. Ich glaube, dass einfach vor-normalisieren typename sollte dies beheben, aber ich habe es nicht getestet.

    
R. Martinho Fernandes 28.05.2015 10:35
quelle
1

Obwohl es bereits eine akzeptierte Antwort gibt, lass mich ein

anbieten

Behebung des Problems

%Vor%

Was macht es?

mit dieser namedtuple_() Implementierung normalisierte die Namen vorher übergibt sie an collections.namedtuple() , wodurch kongruente Namen möglich sind.

Dies ist eine Weiterentwicklung von @R. Martinho Fernandes 'Idee, die Namen vorzumanalisieren.

    
knitti 28.05.2015 11:42
quelle