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.
Benutzeravatar
xWolf
User
Beiträge: 62
Registriert: Sonntag 2. November 2008, 01:21
Wohnort: China

geloest - unicode problem

Beitragvon xWolf » Dienstag 9. Dezember 2008, 09:21

Hallo,

Mein Problem ist das Einlesen von Zeichen aus einer Datei, die uniocode-Zeichen enthalten.

Mein code-Schnipsel:

Code: Alles auswählen

Datensatz = u""
AnzahlBytes = 270
# Position errechnen
.
.
self.f_obj.seek(Position,0) #................Zeiger positionieren
Datensatz = unicode(self.f_obj.read(AnzahlBytes)) #...Datensatz lesen
 


Dabei erhalte ich den Fehler:

Code: Alles auswählen

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 143: ordinal not in range(128)


Wie bringe ich python bei, dass ich die eingelesenen Zeichen in eine Variable des Types: "unicode" speichern kann?

Danke euch.

Wolf
Zuletzt geändert von xWolf am Mittwoch 10. Dezember 2008, 04:01, insgesamt 1-mal geändert.
Lonestar
User
Beiträge: 147
Registriert: Samstag 9. August 2008, 08:31

Beitragvon Lonestar » Dienstag 9. Dezember 2008, 09:40

hi, ich tu mich immer noch ein wenig schwer mit encodings, und hoffe mal ich verzapfe hier nu keinen Unsinn - aber das sieht für mich so aus als wenn du kein Unicode aus deiner Datei einlesen würdest.
Wenn du die Datei einfach direkt mit passendem Encoding öffnest sollte sich dein Problem eigentlich erledigen - Hilfe gibts im WIKI [wiki]Von Umlauten, Unicode und Encodings[/wiki]ganz unten
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 9. Dezember 2008, 10:15

Du gibst kein Encoding an, welches deine Daten haben, also nimmt Python ASCII an, was natürlich crasht, wenn deine Dateien eben nicht durch ASCII repräsentierbar sind.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
xWolf
User
Beiträge: 62
Registriert: Sonntag 2. November 2008, 01:21
Wohnort: China

Beitragvon xWolf » Dienstag 9. Dezember 2008, 10:19

Leonidas hat geschrieben:Du gibst kein Encoding an, welches deine Daten haben, also nimmt Python ASCII an, was natürlich crasht, wenn deine Dateien eben nicht durch ASCII repräsentierbar sind.

Danke,
Hast Du 'nen Tipp, wie ich das encoding angebe?

Wolf
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 9. Dezember 2008, 10:33

Als zweiten Parameter zu ``unicode()`` oder als 1. Parameter zu ``"string".decode()``.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Beitragvon Darii » Dienstag 9. Dezember 2008, 10:43

Over du verwendest codecs.open
Benutzeravatar
xWolf
User
Beiträge: 62
Registriert: Sonntag 2. November 2008, 01:21
Wohnort: China

Beitragvon xWolf » Dienstag 9. Dezember 2008, 10:56

Lonestar hat geschrieben:hi, ich tu mich immer noch ein wenig schwer mit encodings, und hoffe mal ich verzapfe hier nu keinen Unsinn..


Hallo,

Danke fuer den Tipp. Unsinn war das auf keinen Fall. Es hat geklappt, nur hast Du mir ein neues Problem beschehrt.
Und zwar lese ich Datensaetze mit einer bestimmten Laenge in Bytes aus der Datei. Dass klappt auch. Aber nachdem ich den Datensatz gelesen habe, teile ich den Satz in zwei Datenfelder mittels Stringfunktionen wie:

Code: Alles auswählen

Datenfeld1 = Datensatz[0:80]
Datenfeld2 = Datensatz[80:]


Nun kommt der Haken. Vorher waren es ASCII-Zeichen und die Laenge des Strings war auch die Anzahl der Ascii-Zeichen. Nun werden aber bei der Codierung zwei Zeichen zu einem Zeichen zusammengefasst. Somit haut die Teilung des Datensatzes in zwei Felder mittels Zeichenzaehlung per Stringfunktionen nicht mehr hin.

Kennst Du eine Funktion, die nicht die Zeichen sondern die Anzahl Bytes einer Variable zaehlt?

Danke.

Wolf
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Beitragvon Hyperion » Dienstag 9. Dezember 2008, 11:14

Darf man fragen, um was für Daten es da in der Datei geht? Scheint mir ja eine obskure Mischung aus Binär und Textdaten zu sein? Kennst Du das Format näher? Evtl. gibt es ja einen besseren Weg, das zu parsen ...
Benutzeravatar
xWolf
User
Beiträge: 62
Registriert: Sonntag 2. November 2008, 01:21
Wohnort: China

Beitragvon xWolf » Dienstag 9. Dezember 2008, 11:24

Hyperion hat geschrieben:Darf man fragen, um was für Daten es da in der Datei geht? Scheint mir ja eine obskure Mischung aus Binär und Textdaten zu sein? Kennst Du das Format näher? Evtl. gibt es ja einen besseren Weg, das zu parsen ...


Hallo,

Vielleicht sind das obskure Daten. Aber ich schleppe diese Daten seit DOS-Zeiten mit.
Es handelt sich tatsaechlich um bits und bytes.
Ein Datensatz hat die Laenge von 370 bytes. Feld1 hat 74 Bytes und Feld2 die restlichen 296 Bytes. Diese lese ich ein und stelle sie in textform dar. das ist alles.
Da es frueher nur 255 (256 :-) ) ASCII-Zeichen gab und somit ein ASCII-Zeichen = 1 Byte = 8bit war/ist, gab es da kein Problem. Jetzt mit dem unicode, der 2 Bytes zu einem Zeichen vereint und darstellt habe ich nun ein Problem mit dem zaehlen der Bytes. Da die Funktion:

Code: Alles auswählen

 Anzahl = len(Text)

mir nur die Anzahl der darstellbaren Zeichen und nicht die Anzahl in Bytes zurueck liefert, habe ich ein Problem.

Ich brauche eine Funktion, die mir die Laenge in Bytes gibt.
Kennst Du da was?

Wolf
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 9. Dezember 2008, 12:57

In einen Bytestring dekodieren und darauf dann die Anzahl der Bytes zaehlen? Unicode verschmilzt ja bei Bedarf mehrere Bytes zu einem Codepoint und das ist auch gut so, denn normalerweise stellt man darin ja Texte dar und die bestehen aus Zeichen und nicht aus Bytes.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
xWolf
User
Beiträge: 62
Registriert: Sonntag 2. November 2008, 01:21
Wohnort: China

Beitragvon xWolf » Dienstag 9. Dezember 2008, 13:13

Leonidas hat geschrieben:In einen Bytestring dekodieren und darauf dann die Anzahl der Bytes zaehlen? Unicode verschmilzt ja bei Bedarf mehrere Bytes zu einem Codepoint und das ist auch gut so, denn normalerweise stellt man darin ja Texte dar und die bestehen aus Zeichen und nicht aus Bytes.


Richtig. Das ist ja was ich sagte.
Aber stell Dir vor, Du hast eine Datenbank, (nimm mal dBase) und diese Datenbank besteht aus Datensaetzen und Datenfeldern. Und auch da kann ich ja den unicode benutzen. Nur muss ich, wenn ich die Daten in die Datenbank schreibe auf das Byte genau den Datensatz aus den Informationen der Datenfelder zusammensetzen.
Also muss ich zaehlen, unabhaengig ob es nun unicode ist oder nicht. Die Daten auf der Festplatte bestehen nun mal nur aus Bytes.

Gibt es denn irgendeine Moeglichkeit die tatsaechliche Groesse einer Variablen in Bytes zu bestimmen?

Danke
Wolf
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 9. Dezember 2008, 15:45

xWolf hat geschrieben:Gibt es denn irgendeine Moeglichkeit die tatsaechliche Groesse einer Variablen in Bytes zu bestimmen?

Die tatsächliche Größe eines Objektes ist in Python nicht abrufbar. So ist u"abc" nicht zwingend gleich groß wie u"abc", denn es gibt sowohl UCS-2 als auch UCS-4 Varianten von Python die je nach Kompilationseinstellungen Strings im Speicher unterschiedlich darstellen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
xWolf
User
Beiträge: 62
Registriert: Sonntag 2. November 2008, 01:21
Wohnort: China

Beitragvon xWolf » Mittwoch 10. Dezember 2008, 04:34

Leonidas hat geschrieben:Die tatsächliche Größe eines Objektes ist in Python nicht abrufbar. So ist u"abc" nicht zwingend gleich groß wie u"abc", denn es gibt sowohl UCS-2 als auch UCS-4 Varianten von Python die je nach Kompilationseinstellungen Strings im Speicher unterschiedlich darstellen.


Hallo Leonidas,

Richtig. Das war mein Problem,
Also muessen wir es abrufbar machen.

Ich habe mir eine Funktion geschrieben, die die tatsaechliche Laenge der unicode-Zeichenkette in Anzahl-bytes zurueckgibt.

Und zwar nutze ich die hex() Funktion, die mir einen 8-bit, 16-bit oder wie auch immer langen hexadezimalen Wert eines Zeichens zurueckgibt.
Hier das Script.

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

def byteLen(Text):
   # ------------ Variableninitialisierung ---------------
    xlen = 0 # .....Laenge der Zeichenkette in bytes
    i = 0 #.........Schleifenzaehler
    l = len(Text) #.Laenge der Zeichenkette in Zeichen
    hl = 0 #........Anzahl der Hexadezimalen Zeichen
    quo = 0 #.......Quotient auf Hexa-Laenge durch 2
    temp = "" #.....temporaere VAriable
    while  i < l:
       temp = hex(ord(Text[i])) #..Zeichen im Text in Hexa-Wert wandeln
       temp = temp[2:] #...........das '0x' abschneiden - gehoert nicht zum Hexa-Wert
       hl = len(temp) #............Laenge ermitteln
       quo = hl / 2 #..............und durch 2 teilen, ein Hexa-Wert besteht immer aus 2 Zeichen
       if (quo*2) < hl: #..........falls fuehrende '0' fehlt, dann
          temp = "0"+temp #........hinzufuegen um gerade Anzahl an Zeichen zu erhalten
       xlen = xlen + len(temp)/2  # .......und Anzahl zur Gesamtlaenge addieren
       i = i + 1 #.................Zaehler eins rauf
    return xlen #..................Gesamtlaenge zurueckgeben

# nun testen mit einem Zeichen oberhalb ASCII 255 -------------
Text = u"\u0126" # Unicode hex 0126
print "Text:",Text,"Zeichenlaenge:",len(Text)," Byte-Laenge",byteLen(Text)         


Kann man einfach wie oben gezeigt kopieren und ausfuehren. Habe ich auch mit chinesischen Zeichen ausprobiert. Klappt.
Das Script wird einigen Profis vielleicht den Angstschweiss in die Stirn treiben, aber "Entscheidend ist was hinten raus kommt!" - hat schon Helmut Kohl gesagt. :D

Gruss

Wolf
BlackJack

Beitragvon BlackJack » Mittwoch 10. Dezember 2008, 05:28

@xWolf: Und in diesem Fall kommt hinten Mist raus, die Funktion ist total nutzlos. Unicode hat keine Länge in Bytes, das macht auch überhaupt keinen Sinn, weil man Unicode nicht speichern kann.

Wenn Du Unicode-Text speichern willst, musst Du es unter Angabe einer Kodierung als Bytes kodieren. Und *davon* kannst Du dann die Länge in Bytes ermitteln.

Wenn Du die Daten schon ewig mit Dir herum schleppst, vermute ich mal, dass Du eine Kodierung verwendest, bei der immer ein Zeichen einem Byte entspricht!?

ASCII hat übrigens nur 7-Bit.
Benutzeravatar
xWolf
User
Beiträge: 62
Registriert: Sonntag 2. November 2008, 01:21
Wohnort: China

Beitragvon xWolf » Mittwoch 10. Dezember 2008, 06:37

BlackJack hat geschrieben:@xWolf: Und in diesem Fall kommt hinten Mist raus, die Funktion ist total nutzlos. Unicode hat keine Länge in Bytes, das macht auch überhaupt keinen Sinn, weil man Unicode nicht speichern kann.

Wenn Du Unicode-Text speichern willst, musst Du es unter Angabe einer Kodierung als Bytes kodieren. Und *davon* kannst Du dann die Länge in Bytes ermitteln.

Wenn Du die Daten schon ewig mit Dir herum schleppst, vermute ich mal, dass Du eine Kodierung verwendest, bei der immer ein Zeichen einem Byte entspricht!?

ASCII hat übrigens nur 7-Bit.


Sorry,

Dann hast Du es nicht ausprobiert.
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. 1Wort = 2Byte/ 1Byte = 8bit!

Und auch wenn der Ascii-Code nur 7bit lang ist, also 0-127, wird trotzdem ein Byte abgespeichert, also binaer 01111111!
Auf der Festplatte stehen halt nur Bytes.

Und tatsaechlich repraesentiert ein Byte im Ascii-Code ein Zeichen. Wenn nun 2 Byte fuer ein Zeichen verwendet werden, ist das verstaendlich, trotzdem ist es nicht nutzlos zu wissen, wie lang eine Zeichenkette in Byte ist. Ich habe das versucht mit dem weiter o.g. Beispiel Datenbank/Datensatz/Datenfeld deutlich zu machen.

Wolf

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder