Seite 1 von 2
kleines Problem mit der Zeichenkodierung
Verfasst: Mittwoch 15. September 2010, 22:21
von Fjunch-click-
Hallo,
ich probiere gerade ein wenig mit Strings herum (bin noch totaler Anfänger) und habe da ein kleines Problem:
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: UTF-8 -*-
vers = """Wer reitet
so spät
durch Nacht und Wind"""
zeilen = vers.split("\n")
print vers
print
print zeilen
raw_input()
Wenn ich dies ausführe, bekomme ich folgende Ausgabe:
Code: Alles auswählen
Wer reitet
so spät
durch Nacht und Wind
['Wer reitet', 'so sp\xc3\xa4t', durch Nacht und Wind',]
Wie man sieht, stimmt die Zeichenkodierung, wenn vers ausgegeben wird, nach dem splitten stimmt sie allerdings nicht mehr. Woran liegt das?
System ist Debian Testing mit Python 2.6.6.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Mittwoch 15. September 2010, 22:40
von cofi
Sie stimmt auch bei 2. nur ist das eben die `repr` Ausgabe des Strings.
Du solltest im uebrigen Unicode-Strings nutzen (Unicode Literale haben ein `u` vor dem eigtl String), die sparen Kopfschmerzen.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Mittwoch 15. September 2010, 22:56
von Hyperion
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Mittwoch 15. September 2010, 23:40
von Fjunch-click-
Tja, der Link als Antwort ist ja vielleicht nett gemeint, für einen absoluten Anfänger aber leider nicht gerade leicht zu verstehen. Und wie ich das Problem nun löse, kann ich daraus ehrlich gesagt nicht herauslesen. Alles nicht ganz einfach, wenn man gerade beginnt, sich mit Python zu befassen. Für erfahrene Python-Programmierer ist das alles wahrscheinlich so banal und einfach, dass sich jede ausführlichere Antwort erübrigt.
Naja, trotzdem danke für die Antworten.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Mittwoch 15. September 2010, 23:51
von BlackJack
@Fjunch-click-: Auf die Darstellung der Liste bezogen gibt es kein Problem was man lösen muss. Da sind die Daten drin die auch in der Zeichenkette enthalten sind, sie werden halt nur anders dargestellt als Du erwartet hast.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 09:35
von Rebecca
Printe mal zeilen[1]...
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 10:19
von Fjunch-click-
Tja, jetzt bin ich eigentlich noch verwirrter als vorher. Denn nachdem ich gestern mit einem Freund alles mögliche probiert habe und es nicht hinbekommen hatte, funktioniert es heute ...
Zur Erklärung:
Es handelt sich bei der Geschichte um eine Übung aus dem Buch "Python für Kids":
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: UTF-8 -*-
#
# politiker.py - Phrasendreschmaschine
# kap05 - Seite 140
from random import choice
subjekt = """DER UNBEDINGTE WILLE
DAS ERKLÄRTE ZIEL
DIE SELBSTVERSTÄNDLICHE PFLICHT
DIE GESCHICHTLICHE AUFGABE
DIE UNERWARTETE GNADE
DIE TIEFE EINSICHT
DIE EINFACHE ABSICHT
DIE SCHLICHTE NOTWENDIGKEIT
DIE EINDEUTIGE ERKENNTNIS
DIE HOHE AMTSPFLICHT"""
weise = """HIER UND JETZT
IN ALLER OFFENHEIT
IN GEMEINSAMER ANSTRENGUNG
ZWISCHEN GESTERN UND MORGEN
OHNE "WENN" UND "ABER"
NOTFALLS IM ALLEINGANG
GEGEN ALLE WIDERSTÄNDE
GANZ UNMISSVERSTÄNDLICH
IN GUT UND BÖSE
AUCH GEGEN DEN ZEITGEIST"""
ziel = """MITEINANDER ZU REDEN
KRAFTVOLL ANZUPACKEN
NACH VORNE ZU BLICKEN
DIE KONTINUITÄT ZU WAHREN
GANZ BEWUSST ÖSTERREICHISCH ZU SEIN
DAS ZIEL ANZUSTREBEN
LETZTLICH ALLEIN ZU SEIN
DAS ICH VOR DAS WIR ZU STELLEN
DEM VATERLAND ZU DIENEN
GANZ EINFACH OBEN ZU BLEIBEN"""
subjektliste = subjekt.split("\n")
weiseliste = weise.split("\n")
zielliste = ziel.split("\n")
print choice(subjektliste) + ", " + choice(weiseliste) + ", " + \
choice(zielliste) + ", IST DAS GEBOT DER STUNDE!"
print
print choice(subjektliste) + ", " + choice(weiseliste) + ", " + \
choice(zielliste) + ", IST DAS GEBOT DER STUNDE!"
print
print choice(subjektliste) + ", " + choice(weiseliste) + ", " + \
choice(zielliste) + ", IST DAS GEBOT DER STUNDE!"
print
raw_input()
Und dort war es so, dass, wenn ich einfach einen der Strings ausgegeben habe, alles in Ordnung war. Nach der Bearbeitung durch split und choice aber die Umlaute falsch dargestellt wurden.
Seit heute morgen geht es aber!
Keine Ahnung, wahrscheinlich war es einfach nur eine Editoreinstellung (Geany), eine Dokumenteneinstellung oder irgend etwas, was dann erst durch einen Neustart geändert wurde. Wie gesagt, keine Ahnung ...
@colt
Wenn ich übrigens ein "u" vor einen der Strings setze, bekomme ich eine Fehlermeldung:
Code: Alles auswählen
Traceback (most recent call last):
File "politiker.py", line 50, in <module>
choice(zielliste) + ", IST DAS GEBOT DER STUNDE!"
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 18: ordinal not in range(128)
Ich danke euch.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 10:23
von Hyperion
Du solltest Dir dennoch angewöhnen intern mit Unicode zu arbeiten. Dazu gehört auch das Hinterlegen bei Literalen als Unicode-Literale.
Code: Alles auswählen
subjekt = u"""DER UNBEDINGTE WILLE
DAS ERKLÄRTE ZIEL
...
"""
Beim Output codierst Du das ganze entsprechend dann in ein passendes Encoding.
Auch als Anfänger solltest Du Dir meine Links mal angucken. Speziell die Folien haben mir damals schon geholfen, den ganzen Komplex zu verstehen.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 10:54
von Rebecca
Nochmal zu dem was BlackJack und ich meinten:
Code: Alles auswählen
>>> mylist = ["hallö", "welt"]
>>> print mylist
['hall\xc3\xb6', 'welt']
>>> print mylist[0]
hallö
>>> mystring = "hallö welt!"
>>> print mystring
hallö welt!
>>> print repr(mystring)
'hall\xc3\xb6 welt!'
Die repr-Funktion gibt Nicht-ASCII-Zeichen
immer in der Hex-Darstellung aus. Wenn du einfach eine Liste printest, wird auf jedes ihrer Elemente repr angewandt, d.h. wenn du die Liste als ganzes printest, wirst du nie Umlaute sehen. Dafuer muesstest du durch die Liste iterieren und jedes Element printen.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 12:45
von Fjunch-click-
@Rebecca und BlackJack
Habe mal etwas herumprobiert, ist mir jetzt klar geworden. Danke.
@Hyperion
Werde mich mal eingehender damit beschäftigen.
Im Moment ist es aber so, wie es oben schon geschrieben hatte. Wenn ich zum Beispiel vor dem String "subjekt" ein "u" einfüge bekomme ich die oben gepostete Fehlermeldung.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 13:03
von Hyperion
Fjunch-click- hat geschrieben:
Im Moment ist es aber so, wie es oben schon geschrieben hatte. Wenn ich zum Beispiel vor dem String "subjekt" ein "u" einfüge bekomme ich die oben gepostete Fehlermeldung.
Eben! Weil Deine Shell kein utf-8 verarbeiten kann. Python nimmt als default in 2.x ASCII (durch den Coding-Coockie bei Dir nun utf-8) an und encodiert Unicode-Strings bei Output-Operationen in dieses Encoding. Deine Windows-Shell kann aber vermutlich kein utf-8 darstellen, sondern nur einen ISO-8859 o.ä. Zeichensatz. Also musst Du das entsprechende Encoding wählen, damit die Ausgabe lesbar wird
Genau aus diesem Grund lohnt es sich, sich wirklich damit auseinander zu setzen.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 14:15
von Fjunch-click-
Hm, also Windows benutze ich nicht, habe hier Debian Testing laufen. Und ich denke, dass meine Shell UTF-8 darstellen kann, da mein gesamtes System so konfiguriert ist. Hier die Ausgabe von locale:
Code: Alles auswählen
lars@bharani:~$ locale
LANG=de_DE.utf8
LC_CTYPE="de_DE.utf8"
LC_NUMERIC="de_DE.utf8"
LC_TIME="de_DE.utf8"
LC_COLLATE="de_DE.utf8"
LC_MONETARY="de_DE.utf8"
LC_MESSAGES="de_DE.utf8"
LC_PAPER="de_DE.utf8"
LC_NAME="de_DE.utf8"
LC_ADDRESS="de_DE.utf8"
LC_TELEPHONE="de_DE.utf8"
LC_MEASUREMENT="de_DE.utf8"
LC_IDENTIFICATION="de_DE.utf8"
LC_ALL=
lars@bharani:~$
Und in der Shell ist natürlich auch UTF-8 als Kodierung eingestellt.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 14:30
von cofi
Nein das Problem ist nicht die Ausgabe sonst waere es ein `UnicodeEncodeError`, kein `UnicodeDecodeError`.
Du mischst Unicode-Strings mit Bytestrings ohne erstere selbst zu kodieren, darum kracht es.
Schau dir
Stringformatierung an, damit umgehst du das Problem deine Teilstrings zu Unicode-Objekten zu machen.
Ich heisse aber nicht 'colt'.
Edit: Noch etwas zu deinem Coding-Cookie: Wenn du die Emacs-Form benutzt, dann nutze bitte auch valide Namen (`utf-8` in dem Fall). Mehr dazu hier:
http://www.python.org/dev/peps/pep-0263/
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 14:42
von Fjunch-click-
cofi hat geschrieben:
Ich heisse aber nicht 'colt'.
Oh, sorry, weiß selbst nicht, wie ich darauf gekommen bin. :K
Eigentlich habe ich ja gar kein Problem mit Unicode-Strings. Wenn ich die Strings einfach so lasse, wie es im Buch beschrieben ist, funktioniert ja alles.
Werde mir das aber natürlich mal ansehen.
Im Moment werde ich aber erst einmal mit dem Buch weitermachen. Sonst verliere ich mich in irgendwelchen Details, ohne weiter zu kommen.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 15:00
von cofi
Ja es funktioniert. Aber das ist eher Zufall bzw wie in dem Fall, weil alles in der Datei steht und dasselbe Encoding hat.
Bytestrings sind problematisch weil man wissen muss welches Encoding sie haben um mit ihnen zu arbeiten, bei Unicodestrings hat man dieses Problem nicht, weil Python weiss wie es damit arbeiten muss.
Stringformatting solltest du dir aber sofort anschauen, aus dem einfachen Grund, dass du dann keine haesslichen Zeilen hast die das muehsam zusammenbauen, sondern direkt die Form angeben kannst.
Code: Alles auswählen
print choice(subjektliste) + ", " + choice(weiseliste) + ", " + \
choice(zielliste) + ", IST DAS GEBOT DER STUNDE!"
wird zu
Code: Alles auswählen
print "%s, %s, %s, IST DAS GEBOT DER STUNDE!" % choice(subjektliste), choice(weiseliste), choice(zielliste)
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 16:39
von Fjunch-click-
Was ich gerade festgestellt habe:
Wenn ich im Programm dem ersten String (subjekt) ein "u" voranstelle, gibt es die Fehlermeldung.
Mache ich es bei allen drei Strings, funktioniert es wieder.
Naja, wie gesagt, ich mache erst einmal weiter. Habe das Buch ja gerade erst angefangen. Über Stringformatierung kommt da noch was. Ich lasse es mal auf mich zu kommen.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 17:49
von Hyperion
Fjunch-click- hat geschrieben:
Naja, wie gesagt, ich mache erst einmal weiter. Habe das Buch ja gerade erst angefangen. Über Stringformatierung kommt da noch was. Ich lasse es mal auf mich zu kommen.
Stringformatierung ist etwas anderes als die Kodierung von Strings (Unterschied Unicode- zu Bytestrings). Allerdings kann es bei der Formatierung eben eine Rolle spielen, was für Strings man benutzt. In Deinem Falle hast Du sie eben gemischt; da muss Python diese ja vereinheitlichen, sprich eine Sorte in eine andere überführen. Dabei nimmt der Interpreter eben das voreingestellte Encoding zum Dekodieren; passt das aber nun nicht zum Encoding Deiner Datei, gibt es Probleme.
Du solltest auf jeden Fall im Hinterkopf haben, dass es da Probleme gibt; wenn Du Dich nicht jetzt schon mit dem Problematik befassen magst.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 18:15
von Fjunch-click-
OK, würdest du dann sagen, dass man prinzipiell immer Unicode-Strings benutzen sollte? Also, dass selbst ein einfaches
besser ein
sein sollte?
Dann wäre es ja kein Problem, sich das so anzugewöhnen.
Mit der Problematik befassen tue ich mich schon. Ich hoffe aber einfach mal, dass dieses Thema auch in meinem Buch noch zur Sprache kommen wird. Deswegen halte ich für sinnvoll da erst einmal weiterzumachen.
Parallel dazu habe ich gerade angefangen, mir den Python-Kurs im
Full Circle Magazine anzuschauen.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 18:28
von Hyperion
Fjunch-click- hat geschrieben:OK, würdest du dann sagen, dass man prinzipiell immer Unicode-Strings benutzen sollte? Also, dass selbst ein einfaches
Ich würde sagen ja!
Allerdings solltest Du eben schon versuchen, Dich damit ein wenig zu befassen. Spiele doch die Beispiele aus dem wiki und / oder dem Vortrag selber mal in einer Shell durch.
Nur weil in einem Buch darauf (noch) nicht eingegangen wird, bedeutet das ja nicht, dass Du Dich damit noch nicht befassen darfst

Zudem sollst Du ja nicht 2 Tage am Stück Dich nur damit befassen. Nach einer Stunde intensiven Lesens und Vertiefen des Gelernten durch eigenes Ausprobieren, hast Du sicherlich schon mal eine gute Grundlage.
Re: kleines Problem mit der Zeichenkodierung
Verfasst: Donnerstag 16. September 2010, 18:41
von /me
Fjunch-click- hat geschrieben:
Dann wäre es ja kein Problem, sich das so anzugewöhnen.
Unter Python 3 ist Unicode ohnehin Standard. Unter Python 2.6 habe ich mir angewöhnt, an den Anfang jedes Skripts ein
zu setzen um damit den gleichen Effekt zu haben. Das
u vor dem String kann man sich dann sparen.
Trotzdem muss man sich damit auseinandersetzen, was die Verwendung von Unicode bedeutet. Wenn du Dateien speicherst, dann brauchst du eine passende Codierung für das Ausgabeformat. UTF-8 wird da gerne genommen, aber vielleicht möchte ein anderes System ja ISO-8859-15 haben. Encoding und Decoding von und nach Unicode ist ein ganz großes Thema und man sollte verstehen, was da vor sich geht.