Unicode Error bei wx.StaticText

Plattformunabhängige GUIs mit wxWidgets.
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Samstag 2. Februar 2008, 14:09

Hallo,

Ich verarbeite utf-8 Strings aus Webseiten.
Da ich Teile davon im Statusbar ausgebe, wandle ich sie
in iso-8859-1 um, da ich bei einigen Zeichen sonst Fehlermeldungen bekomme. Klappt auch.

Kontrollausgabe der Umwandlung (utf-8 -> Unicode -> iso-8859-1):

Code: Alles auswählen

Original  <type 'str'>
Unicode  <type 'unicode'>
ISO  <type 'str'>
Jetzt sollen Teile davon als Static Text ausgegeben werden.
Und da bekomme ich ständig einen Unicode-Error. Der Typ ist String
<str> und trotzdem die Fehlermeldung:

Code: Alles auswählen

TypeError: String or Unicode type required
Welchen Typ String brauche ich denn für wx.StaticText ?


Hier der Code:

Code: Alles auswählen

print type(SJ.about['names'])

text1 = SJ.about['names']

wx.StaticText(self, -1, (5,10), text1)
Hier die komplette Fehlermeldung:

Code: Alles auswählen

<type 'str'>
Traceback (most recent call last):
File "CheckArtist.py", line 274, in OnEnterPanel3
AAW = AboutArtistWin()
File "CheckArtist.py", line 1797, in __init__
wx.StaticText(self, -1, (5,10), text1)
File "C:\Programme\Python25\lib\site-packages\wx-2.8-msw-unicode\wx\_controls.py", line 1136, in __init__
_controls_.StaticText_swiginit(self,_controls_.new_StaticText(*args, **kwargs))
TypeError: String or Unicode type required
text1 = unicode(SJ.about['names'], 'iso-8859-1') klappt leider auch nicht. Dieselbe Meldung.

Befreit mich bitte von dem Wahnsinn, bevor ich irre werde :shock:

Gruß, Seven
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Samstag 2. Februar 2008, 14:30

snakeseven hat geschrieben:Ich verarbeite utf-8 Strings aus Webseiten. Da ich Teile davon im Statusbar ausgebe, wandle ich sie in iso-8859-1 um
Hallo Seven!

1.) Füttere wxPython-Widgets wo immer möglich mit Unicode und gehe davon aus, dass du von diesen auch Unicode zurück bekommst. Rate jedem dazu, die wxPython-Unicodeversion zu installieren und einen weiten Bogen um die ANSI-Version zu machen.

2.) ``wx.StaticText(self, -1, (5,10), text1)``
Hier stimmt die Reihenfolge der Parameter nicht.

Code: Alles auswählen

wx.StaticText(parent, id, label, pos, size, style, name)
mfg
Gerold
:-)
Zuletzt geändert von gerold am Samstag 2. Februar 2008, 14:32, insgesamt 1-mal geändert.
[url]http://halvar.at[/url] | [url=http://halvar.at/elektronik/kleiner_bascom_avr_kurs/]Kleiner Bascom AVR Kurs[/url]
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 2. Februar 2008, 14:30

Warum übergibst du ihm nicht einfach den Unicode-String? UFT-8 in ISO-8859-1 zu umzukodieren ist sowieso eine dumme Idee.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Frank aka Ch3ck3r
User
Beiträge: 49
Registriert: Dienstag 13. November 2007, 21:56
Wohnort: Berlin
Kontaktdaten:

Samstag 2. Februar 2008, 14:31

falsch

Code: Alles auswählen

wx.StaticText(self, -1, (5,10), text1)
richtig

Code: Alles auswählen

wx.StaticText(self, -1, text1, pos=(5,10))
greez
kostenlose TS2-Server für jeweils 31 Tage:
http://www.ts-onlyfree.de
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Samstag 2. Februar 2008, 15:29

Frank aka Ch3ck3r hat geschrieben:falsch

Code: Alles auswählen

wx.StaticText(self, -1, (5,10), text1)
richtig

Code: Alles auswählen

wx.StaticText(self, -1, text1, pos=(5,10))
greez
Hallo Frank,
das war der Fehler, so bekomme ich auch keine Fehlermeldung mehr.

Würde ja gerne durchgehend mit Unicode arbeiten, bis zur Ausgabe als Textdatei zumindest. Aber irgendwo ist noch ein Fehler, wenn ich nur mit Unicode arbeite. Bei der Ausgabe in der Statusbar muckt wxPython bei Sonderzeichen rum!?

Habe die Unicodeversion installiert und muß jetzt mal genau nachsehen, wo mir die Codierung aus dem Ruder läuft. Wohlmöglich sind einige der aufgerufenen Seiten nicht utf-8, ich schau mal.

Danke zusammen,
Seven
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Sonntag 3. Februar 2008, 18:56

Hallo,
das ausschließliche Arbeiten mit Unicode ist leider nicht die Lösung meines Problems. Der Name Smokin' wird in StaticText als Smokin’ wiedergegeben und auch beim Speichern in eine Textdatei wird der Name falsch geschrieben.

Mir stellt sich jetzt die Frage, ob Python beim Einlesen von UTF-8 codierten HTML-Seiten mittels Urllib2 die Zeichen in Unicode wandelt, oder ob ich mich da selbst drum kümmern muß ? Da das Python interne Format Unicode ist, hatte ich gehofft, dass sich Python darum kümmert :roll:

Grüße, Seven
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Sonntag 3. Februar 2008, 19:38

Also,
das mit StaticText konnte ich so lösen:

Code: Alles auswählen

wx.StaticText(self, -1, unicode(text1,'utf-8'), (5,10))
Damit beantwortet sich auch die Frage, ob Python beim Einlesen per Urllib in Unicode wandelt. Tut es nicht. Schade eigentlich. Wäre das nicht konsequent, wo doch Python defaultmäßig mit Unicode arbeitet?

Jetzt muß ich nur noch rauskriegen, wie ich das fehlerfrei als Text gespeichert bekomme :?:

Grüße, Seven
BlackJack

Sonntag 3. Februar 2008, 19:48

Erstmal arbeitet Python intern nicht defaultmässig mit Unicode. Und dann ist `urllib2` nur für den Transport der Daten zuständig und wandelt nichts automatisch um. Da gehen *Bytes* über die Verbindung, keine Zeichen. Bei HTML braucht man dafür einen Parser. Wie das kodiert ist, kann ja zum Beispiel im ``<head>`` in einem ``<meta>``-Tag angegeben sein. Wobei das was da steht, nicht unbedingt stimmen muss. Bei HTML muss man mit allem rechnen.
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Sonntag 3. Februar 2008, 20:19

BlackJack hat geschrieben:Erstmal arbeitet Python intern nicht defaultmässig mit Unicode.
Hm, liest man das nicht ständig?
BlackJack hat geschrieben:Bei HTML braucht man dafür einen Parser
Ok, den gibts ja auch für Python. Verstanden habe ich den allerdings noch nicht!? Aber ich werte nur die Seiten eines bestimmten Portals aus und die sind alle utf-8. So kann ich erstmal mit meinem eigenen, kleinen Parser leben.

Gruß, Seven
BlackJack

Montag 4. Februar 2008, 09:53

Also ich lese das nicht ständig. :-)

Man sollte selbst mit Unicode arbeiten wenn man Text verarbeitet, das ist die Empfehlung, die man oft liest.

Aber wie gesagt, was da über `urllib2` herein kommt sind Bytes. Du kannst damit ja auch Bilder oder beliebige andere Daten übertragen.

Wenn Du nur UTF-8 kodierte Seiten abrufst, ist das dekodieren mit ``data.decode('utf-8')`` oder ``unicode(data, 'utf-8')`` ja kein grosses Problem.
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Montag 4. Februar 2008, 12:25

BlackJack hat geschrieben: Wenn Du nur UTF-8 kodierte Seiten abrufst, ist das dekodieren mit ``data.decode('utf-8')`` oder ``unicode(data, 'utf-8')`` ja kein grosses Problem.
Stimmt, aber mein Weg zu dieser Einsicht war etwas lang :wink: wie man hier live miterleben konnte.
Jetzt habe ich nur noch das Problem mit dem Speichern von Sonderzeichen in eine Textdatei, als da wären (',´,`,diverse Symbole). Egal, wie ich die vor dem Speichern umwandle (für PC hab ich auch 'cp1252' probiert), ich bekomme immer die Fehlermeldung

Code: Alles auswählen

UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 6: ordinal not in range(128)
Speichere die Sachen deshalb erstmal so ab, wie sie programmintern vorliegen, was zu eher unschönen Einträgen führt:

Code: Alles auswählen

Smokin’ Circles%302376097%
Auch bei skandinavischen Sonderzeichen wird gemeckert. Was streichen die auch ihre Buchstaben durch !? :P

Gruß, Seven
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Montag 4. Februar 2008, 12:57

Hallo Seven!

Idealerweise arbeitest du innerhalb deines Programmes mit Unicode. Das bedeutet:

- Wenn du etwas ins Programm einliest, z.B. eine HTML-Datei, dann wandelst du diese sofort beim Empfang nach Unicode um.

- Dann arbeitest du mit den Unicode-Daten, ohne dass du dich um irgendein besonderes Encoding kümmern musst. Du kannst Unicode direkt zum Anzeigen an wxPython-Widgets übergeben. Und du kannst davon ausgehen, dass du von einem wxPython-Widget Unicode zurück bekommst. Zumindest dann, wenn die wxPython-Unicode-Version installiert ist.

- Zum Speichern konvertierst du die Daten wieder in ein Encoding. Idealerweise arbeitest nur du mit deinem Programm mit den Daten. Dann kannst du ohne lange zu überlegen, die Daten **von Unicode** nach **UTF-8** umwandeln. Da du intern mit Unicode arbeitest, brauchst du dir dabei keine Gedanken über das ursprüngliche Encoding machen.
Wenn andere Programme auch damit arbeiten müssen, dann nimmst du das Encoding, welches von den anderen Programmen angenommen wird. Meistens ist das das ``locale.getpreferredencoding()``.

- Wenn du dann die Daten wieder in dein Programm einlesen möchtest, dann weißt du ja, ob du UTF-8 oder ``locale.getpreferredencoding()`` zum Speichern verwendet hast. Dieses Encoding nimmst du beim Laden der Daten wieder her um diese für dein Programm nach Unicode umzuwandeln. Und schon hast du im Programm wieder den eindeutigen Zustand: "Unicode".

Wie du gezielt von und nach Unicode umwandelst, erfährst du hier: http://www.python-forum.de/topic-5095.html

lg
Gerold
:-)


PS: --> http://www.python-forum.de/topic-12026.html <--


.
[url]http://halvar.at[/url] | [url=http://halvar.at/elektronik/kleiner_bascom_avr_kurs/]Kleiner Bascom AVR Kurs[/url]
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Montag 4. Februar 2008, 13:30

Gut, werde ich mal angehen. Bislang habe ich nur an den Stellen in Unicode gewandelt, wo eine Übergabe an WX-Widgets stattfindet.

Ist es effektiver, die komplette geladene Seite in Unicode umzuwandeln, oder nur die einzelnen Strings, die ich da raus picke?
(ca. 4-5 Strings pro Seite)

Gruß, Seven
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Montag 4. Februar 2008, 13:45

snakeseven hat geschrieben:Ist es effektiver, die komplette geladene Seite in Unicode umzuwandeln, oder nur die einzelnen Strings, die ich da raus picke?
Hallo Seven!

Das ist keine Frage der Effizienz. Wenn du die ganze Seite nach einem Text durchsuchst, dann sollte vorher schon die ganze Seite Unicode sein. Also in deinem Fall, würde ich ohne lange zu überlegen, die Seite zuerst mit ``urllib2.urlopen`` öffnen. Dann den Header nach dem Encoding durchsuchen. Wenn das Encoding angegeben ist, dann weißt du das Encoding. Wenn das Encoding nicht angegeben wurde, es sich aber um eine XHTML-Seite handelt, dann ist es UTF-8. Ansonsten ist es ISO-8859-15.

Mit dieser Information kannst du den HTML-Text nach Unicode umwandeln. Und danach kannst du aus dem Unicode-Text raussuchen was du möchtest, ohne dich jemals wieder um das Encoding kümmern zu müssen. Erst beim Speichern wandelst du die Texte wie im vorherigen Beitrag beschrieben wieder in ein definiertes Encoding um.

lg
Gerold
:-)


PS: --> http://chardet.feedparser.org/ <--

.
Zuletzt geändert von gerold am Montag 4. Februar 2008, 14:04, insgesamt 2-mal geändert.
[url]http://halvar.at[/url] | [url=http://halvar.at/elektronik/kleiner_bascom_avr_kurs/]Kleiner Bascom AVR Kurs[/url]
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BlackJack

Montag 4. Februar 2008, 13:47

snakeseven hat geschrieben:Jetzt habe ich nur noch das Problem mit dem Speichern von Sonderzeichen in eine Textdatei, als da wären (',´,`,diverse Symbole). Egal, wie ich die vor dem Speichern umwandle (für PC hab ich auch 'cp1252' probiert), ich bekomme immer die Fehlermeldung

Code: Alles auswählen

UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 6: ordinal not in range(128)
Was hast Du denn da genau gemacht? Da wird anscheinend versucht eine Unicode-Zeichenkette als ASCII zu kodieren. Dann kannst Du die aber vorher nicht in cp1252 kodiert haben, weil's dann ja keine Unicode-Zeichenkette mehr wäre.
Speichere die Sachen deshalb erstmal so ab, wie sie programmintern vorliegen, was zu eher unschönen Einträgen führt:

Code: Alles auswählen

Smokin’ Circles%302376097%
Diese Information ist ohne Kodierungsangabe sinnlos. Was steht denn da *genau* in der Datei? Wenn Du einfach den Text hier zeigst, der nach dem öffnen in einem Texteditor erscheint, reicht das nicht um zu sagen was in der Datei steht, weil der Texteditor die Bytes ja auch wieder interpretiert. Das kann korrektes UTF-8 sein, das der Editor aber als cp1252 anzeigt, oder aber auch "doppelt" kodiertes UTF-8, das vom Editor als UTF-8 dekodiert wurde.

In Dateien sind grundsätzlich nur Bytes und keine Zeichen gespeichert. Welche Bytewerte als welche Zeichen interpretiert werden, hängt immer von der Anwendung ab, die die Bytes einliest oder raus schreibt. Ausserhalb der Werte für ASCII-Zeichen gehen da die Meinungen auseinander und man muss immer mit dazu sagen welche Kodierung verwendet werden soll.

Ob es effektiver ist nur die Teile, die Du heraus pickst um zu wandeln, hängt von der Grösse der HTML-Dateien und der Anzahl der extrahierten Zeichenketten ab. Ich würd's erst einmal komplett umwandeln, das ist einfacher, dann kann man nichts vergessen. Bei solchen "Mikro"-Optimierungen gilt das Motto "Quelltext schreiben bis er läuft, verbessern bis er korrekt läuft, und dann eventuell optimieren.". Wobei dem letzten Punkt eine Untersuchung mit dem Profiler vorausgehen sollte, damit seine Zeit auch in die richtigen Programmstellen investiert.
Antworten