>>> u'%s' %'ä'

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.
Antworten
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

Ich verstehe immer noch nicht, wie das mit den Codings funktioniert. Hab mir jetzt über ne Stunde was zu Umlauten, Unicode und Encodings durchgelesen, aber irgendwie kann ich das alles nicht auf mein Problem beziehen.

Code: Alles auswählen

>>> u'%s' %'d'
u'd'
>>> u'%s' %'ä'

Traceback (most recent call last):
  File "<pyshell#71>", line 1, in <module>
    u'%s' %'ä'
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
>>> u'ä'
u'\xe4'
Und meine genaue Frage ist: Worin liegt der entscheidende Unterschied in der Verarbeitung der 3 Beispiele und natürlich wie kann ich die Fehlermeldung vermeiden und erreichen, dass u'%s' %'ä' zu u'\xe4' wird?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Fall zwei macht den entscheidenden Fehler. Du verknüpfst einen Bytestring mit einem Unicodestring. Also muss Python nun einen der beiden umwandeln. In diesem Falle wird wohl ein Unicodetsring erzeugt, also muss der Bytestring "ä" in Unicode gewandelt werden. Python (2.x) nimmt da als Standard ASCII an. Damit kracht es natürlich, weil "ä" nun einmal nicht im ASCII-Zeichenvorrat vorkommt.

Beim ersten Fall ist "d" zwar auch Bytestring und auch der wird (implizit) in Unicode gewandelt, aber "d" ist eben im ASCII-Zeichensatz enthalten und kann daher problemlos gewandelt werden.

Probiere mal folgende Ausdrücke:

Code: Alles auswählen

u'%s' % u'ä'
u'%s' % 'ä'.decode("<dein shell encoding>")
Das sollte klappen ;-)

Ach ja, lies mal die Links in meiner Sig :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Hallo,

Code: Alles auswählen

>>> u'%s' % u'ä'
u'\xe4'
>>> u'%s' % 'ä'.decode('utf8')
u'\xe4'
Du hast versucht, einen unicode string (u'%s') mit einem byte string ('ä') zusammenzubringen.

Und die Fehlermeldung zeigt folgendes:
Das 'ä' wird unter Python 2 nicht als unicode string (u'\xe4'), sondern in Deinem encoding (ich gehe jetzt bei Dir mal von latin-1 aus, da in Deiner Fehlermeldung das Byte 0xe4 moniert wird) dargestellt (intern, nicht am Bildschirm).
Das u'%s' erwartet allerdings einen unicode string, erhält aber ein '\xe4' (in latin-1 codiertes 'ä'!)... und dann nimmt der Fehler seinen Laufe... ;-)

mutetella


Die unicode/encoding-Geschichte macht einen sehr verwirrenden Eindruck... aber irgendwann begreift man das immer mehr. Was ich mir dabei immer wieder vor Augen halten muss: unicode ist KEIN encoding.
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

mutetella hat geschrieben:Was ich mir dabei immer wieder vor Augen halten muss: unicode ist KEIN encoding.
Ich glaube, dass das wirklich ein ganz entscheidender Punkt ist, den man zum Verständnis braucht.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

/me hat geschrieben:
mutetella hat geschrieben:Was ich mir dabei immer wieder vor Augen halten muss: unicode ist KEIN encoding.
Ich glaube, dass das wirklich ein ganz entscheidender Punkt ist, den man zum Verständnis braucht.
Vor allem noch spezieller, dass Unicode != utf-8 / utf-16 / utf-32 ist.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Vielen ist nicht klar, dass beim Eintippen von:

Code: Alles auswählen

a = 'öäü'
a = u'üöä'
im Editor oder in der Interpretershell sehr viel Encoding-Magie passiert, bis Python an das richtige Zeichen kommt. Im Falle der Datei sind das:
- Eingabe-Encoding des Editors
- Ausgabe-Encoding des Editors (hier kann Fensterausgabe von Dateiausgabe verschiedenen sein, falls der Editor "Schreibe Datei als Encoding XY..." unterstützt)
- Eingabeencoding der Datei in Python - wird über # coding: XXX annotiert
- implizite Wandlung von u''-Strings zu interner Unicode-Repräsentation

Das sind recht viele Stellen, an denen es haken kann. Da scheinen selbst IDE-Entwickler das Setzen des richtigen Flags hier und da zu vergessen (wie neulich ein Post hier zeigte - weiss leider den IDE-Namen nicht mehr)
JonasR
User
Beiträge: 251
Registriert: Mittwoch 12. Mai 2010, 13:59

jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

... wenn wir schon gerade dabei sind:
iPython hat seit 0.12 endlich auch keine unicode/encoding Probleme mehr, was mich sehr freut... immer dann, wenn es um die korrekte Darstellung ging musste man in die Pythonshell wechseln, was ich natürlich ständig vergessen hab'... ;-)

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
snafu
User
Beiträge: 6736
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

mutetella hat geschrieben:iPython hat seit 0.12 endlich auch keine unicode/encoding Probleme mehr
Das sind doch sehr schöne Neuigkeiten. Das nächste Ubuntu-Release wird übrigens iPython in der Version 0.12 im Repo haben (noch ist es ja die 0.10). :)
Antworten