geloest - unicode problem

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.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Beitragvon Darii » Mittwoch 10. Dezember 2008, 10:51

xWolf hat geschrieben:Es kommt genau das heraus, was ich erwarte. Der Hex-Wert 0x0126 entspricht genau 2 Byte. Und das ist es, was ich wissen will. Auch UNICODE hat eine Laenge in Bytes oder wie sollen sonst Daten auf der festplatte oder im RAM abgelegt werden? Auch mit Objektphilosophie und Hochsprachen, bleibt die Technik unten drunter immer noch die selbe.
Indem man die Unicode-Zeichenkette irgendwie kodiert. Es ist völlig sinnfrei die Größe eines Unicode-String in Byte messen zu wollen, ohne vorher die Kodierung festlegen. Ich kann den String auch als Array von 64bit-Integern speichern, dann wäre jedes Zeichen 8 Byte groß.

Code: Alles auswählen

In [16]: Text = u"\u0126"

In [17]: len(Text.encode("utf-7")), len(Text.encode("utf-16"))

Out[17]: (5, 4)

BlackJack

Beitragvon BlackJack » Mittwoch 10. Dezember 2008, 11:04

@xWolf: Ich brauche es nicht ausprobieren, das ist ein grundsätzliches Verständnisproblem bei Dir. Unicode hat *keine* Länge in Bytes, weil Unicode nur ein abstraktes Konzept ist. Wenn Du das im RAM oder auf Platte speichern möchtest, musst Du das mit einer konkreten Kodierung tun. Dabei kommt dann eine Folge von Bytes heraus, die eine Länge hat. Das ist dann aber kein Unicode mehr.

Du kannst Unicode-Objekte nicht auf Platte schreiben -- Du musst sie vorher immer in eine Folge von Bytes umwandeln. Wie Unicode-Objekte intern gespeichert werden, hat Dich nicht zu interessieren. Das kann je nach Python-Implementierung, -Version, oder sogar Optionen, die beim Übersetzen des Interpreters angegeben wurden, unterschiedlich sein.

Deine Funktion ist sinnlos, weil sie soweit ich das sehe mit keiner Kodierung übereinstimmt. Gebräucliche Kodierung, die Zeichen mit unterschiedlichen Längen kodiert ist UTF-8:

Code: Alles auswählen

In [224]: byteLen(u'ä')
Out[224]: 1

In [225]: len(u'ä'.encode('utf-8'))
Out[225]: 2


Hier kommt zum Beispiel zum tragen, dass ASCII ein 7-Bit-Code ist, weil UTF-8 nur ASCII-Zeichen als 1 Byte kodiert und das 'ä', obwohl der Unicode-Codepoint als Zahl noch in ein Byte passen würde, in zwei Bytes kodiert wird. Wenn Du in Deinen Daten Umlaute hast, dann sind sie nicht ASCII, weil alle Zeichen mit Bytewerten über 127 eben nicht ASCII sind. Und auch dort muss man, um zu wissen was denn nun zum Beispiel ein 'ä' sein soll, eine Kodierung dazu sagen.

Also noch einmal: Man kann nicht sagen wie lang ein Unicode-Objekt in Bytes ist, ohne das man auch eine konkrete Kodierung dazu sagt. Und um diese Länge zu ermitteln ist es wesentlich einfacher das Unicode-Objekt einfach zu kodieren und dann zu schauen wie lang das Ergebnis davon ist, als so eine überkomplizierte Funktion zu verwenden.

Wenn Du Deine Daten schon so lange mit Dir rumschleppst verwendest Du wahrscheinlich eine Kodierung bei der ein Zeichen einem Byte entspricht, dann kannst Du auch einfach `len()` auf dem Unicode-Objekt verwenden.
Benutzeravatar
xWolf
User
Beiträge: 62
Registriert: Sonntag 2. November 2008, 01:21
Wohnort: China

Beitragvon xWolf » Mittwoch 10. Dezember 2008, 12:42

BlackJack hat geschrieben:@xWolf: Ich brauche es nicht ausprobieren, das ist ein grundsätzliches Verständnisproblem bei Dir.....


OK, dann habe ich aber ein naechstes Problem.
Die Daten die ich bearbeiten will, sind bereits durch ein anderes programm gelaufen.
Wie finde ich den heraus wie die codiert sind?
Lade ich die Daten in eine Liste und lasse mir die Daten waehrend des Ladevorgangs auf der konsole anzeigen, werden die Umlaute korrekt dargestellt.
In der Liste nicht.
Oeffne ich die Datei mit codecs.open... werden zwar die Umlaute richtig dargestellt aber die Laenge eines Datenfeldes ist nun unbestimmt, da ja entsprechend der Codierung und der Anzahl der Umlaute pro Datenfeld nun die Groesse variiert und ich schon Zeichen aus dem naechsten Datenfeld in das aktuelle mit einlese.

Die Daten habe ich das letzte mal mit Gambas - dem Basic-Interpreter bearbeitet, bei dem diese Codiererei keine Rolle spielte.

Hmmm. :(
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Beitragvon helduel » Mittwoch 10. Dezember 2008, 13:07

xWolf hat geschrieben:Wie finde ich den heraus wie die codiert sind?
Lade ich die Daten in eine Liste und lasse mir die Daten waehrend des Ladevorgangs auf der konsole anzeigen, werden die Umlaute korrekt dargestellt.
In der Liste nicht.

Wie sehen die Daten in der Liste denn aus?
BlackJack

Beitragvon BlackJack » Mittwoch 10. Dezember 2008, 20:33

@xWolf: Wie die Daten kodiert sind, musst Du entweder wissen, oder ausprobieren. Such Dir zum Beispiel Umlaute und schau Dir in den Daten an welche Bytewerte die haben und such dann die dazu passende Kodierung.

In Listen werden die Elemente in ihrer `repr()`-Darstellung angezeigt, damit man sehen kann, was da *wirklich* drin steht. Das bedeutet bei `str` und `unicode`, dass alles ausserhalb von ASCII als Escapesequenz dargestellt wird.

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]