Hallo,
ich weiß, zum Thema Unicode in Python gibt es bereits viele Themen mit Antworten zu Problemen. Ich kann verstehen, wenn die meisten sicherlich bei diesem Thema schon etwas genervt sind. Ich habe auch schon viel durchsucht, viel gelesen, unteranderem die Links aus Hyperions Signatur. Und trotzdem habe ich es irgendwie noch nicht so ganz verstanden und bekomme mein Problem nicht gelöst.
Nun zu meinem Problem:
Mein Programm liest zuersteinmal bestimmte Zellen einer Exceltabelle aus, welche auch Umlaute etc. enthalten. Danach printed das Programm die Zellen in jeweils eine Zeile einer neuerstellten Textdatei, ich nenne sie einfach mal Exceltext.txt. Es werden allerdings nur die Zellen in die Textdatei geschrieben, die keine Umlaute etc. enthalten. Gebe ich in der print-Funktion ein Encoding ("utf-8") and, werden alle Zellen in die Datei geschrieben. Also so wie ich es auch will und eigentlich auch verstehe.
Nun liest mein Programmn auch eine Textdatei Zeile für Zeile ein, in den Zeilen steht in etwa das gleiche wie in den Zellen der Exceltabelle, sie enthalten also auch Umlaute. Nun schreibt das Programm die Zeilen in eine neue Textdatei, Text_neu.txt. Hier gebe ich kein Encoding an, es werden jedoch alle Zeilen, auch die mit Umlauten in die neue Textdatei Text_neu.txt geschrieben. Gebe ich ein Encoding ("utf-8") an, bekomme ich eine Fehlermeldung ("UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 38: ordinal not in range(128)"). Warum muss ich bei der selben Funktion einmal ein Encoding benutzen und einmal nicht?
Danach liest mein Programm die beiden neu erstellten Textdateien (Exceltext.txt und Text_neu.txt) ein. Benutze ich die normale BIF open werden die Umlaute aus Exceltext.txt nicht als Umlaute geprinted wenn ich die Zeilen auf die Shell printe, aus der Text_neu.txt Datei jedoch schon. Deshalb nutze ich um dieExceltext.txt datei zu öffnen das codecs-Modul mit der codecs.open Funktion und gebe als Encoding "utf-8" an. Diese funktioniert bei der Text_neu.txt allerdings nicht.
Möchte ich nun die beiden Dateien Zeile für Zeile vergleichen und printe sie auf die Shell, sehen sie ja auch erstmal gleich aus. Aber das ist natürlich nur auf der Shell. In wirklichkeit bekomme ich eine Warnung ("UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal") und mein Programm sagt mir, dass die Zeilen eben nicht gleich sind.
Wie bekomme ich dieses Problem gelöst, bzw. viel schöner wäre es, wenn ich verstehen würde, warum das Problem auftritt?
Achja, ich nutze Python 2.7 auf einem Windows 7 Rechner, falls das eine Rolle spielt.
Vielen Dank für eure Hilfe, und nochmals entschuldigung, falls ich hier einige vielleicht Nerven sollte mit einem neuen Thema zu Unicode in Python!
Gruß,
TweetMiner
Unicode mit Nichtunicodestring vergleichen
Dein Problem ist, dass du beim *EINLESEN* kein encoding angibst. Das bedeutet, dass deine eingelesenen Strings keine unicode-objekte sind, sondern stattdessen byte-strings. Du solltest schon beim oeffnen zb das codecs-modul benutzen, und dort das richtige encoding - in deinem Fall wohl utf-8 - angeben.
Dann sind die strings aus der Datei gleich unicode-Objekte, und schreiben kannst du sie wieder mit einem expliziten encoding.
Auch dazu waere das codecs-Modul besser geeignet, statt print zu benutzen.
Dann sind die strings aus der Datei gleich unicode-Objekte, und schreiben kannst du sie wieder mit einem expliziten encoding.
Auch dazu waere das codecs-Modul besser geeignet, statt print zu benutzen.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Hallo,
so ganz ohne Code ist es immer schwierig etwas wirklich stichhaltiges zu sagen.
Eines vorweg: Unicode != utf-8. Ich weiß nicht, ob Dir das schon klar ist?
Du sagst, dass Du etwas in eine Datei schreibst, gleichzeitig fällt aber das Wort ``print``. Normalerweise nutzt man dafür ja eher die ``write``-Methode eines File objects. Da sehe ich Aufklärungsbedarf.
Generell solltest Du intern in Deinem Programm immer mit Unicode arbeiten, also alles, was in Dein Programm "rein kommt" entsprechend mit ``decode("some_encoding")`` in Unicode wandeln und alles, was Du raus schreibst erst unmittelbar davor wieder in ein spezielles Encoding wandeln, z.B. utf-8. Ich vermute irgend wo vermischt Du die Datentypen Unicodestring und Bytecodestring; das führt zu einem impliziten Cast und der nimmt in Python 2.x ASCII als Standardencoding für Bytestrings an. Sind also in dem Bytestring nicht ASCII Zeichen enthalten, kracht es an der Stelle.
Zeig uns doch mal ein minimales Beispiel; ich denke damit kommen wir der Sache eher auf die Spur.
so ganz ohne Code ist es immer schwierig etwas wirklich stichhaltiges zu sagen.
Eines vorweg: Unicode != utf-8. Ich weiß nicht, ob Dir das schon klar ist?
Du sagst, dass Du etwas in eine Datei schreibst, gleichzeitig fällt aber das Wort ``print``. Normalerweise nutzt man dafür ja eher die ``write``-Methode eines File objects. Da sehe ich Aufklärungsbedarf.
Generell solltest Du intern in Deinem Programm immer mit Unicode arbeiten, also alles, was in Dein Programm "rein kommt" entsprechend mit ``decode("some_encoding")`` in Unicode wandeln und alles, was Du raus schreibst erst unmittelbar davor wieder in ein spezielles Encoding wandeln, z.B. utf-8. Ich vermute irgend wo vermischt Du die Datentypen Unicodestring und Bytecodestring; das führt zu einem impliziten Cast und der nimmt in Python 2.x ASCII als Standardencoding für Bytestrings an. Sind also in dem Bytestring nicht ASCII Zeichen enthalten, kracht es an der Stelle.
Zeig uns doch mal ein minimales Beispiel; ich denke damit kommen wir der Sache eher auf die Spur.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
-
- User
- Beiträge: 12
- Registriert: Donnerstag 26. Januar 2012, 08:35
Vielen Dank erstmal für eure schnelle Hilfe.
@deets: Bei welchem Einlesen meinst du? Die Textdatei mit den Daten aus der Exceltabelle (Exceltext.txt) öffne ich über das codecs-Modul, die andere Textdatei (Text_neu.txt) kann ich nur über die BIF open öffnen. Versuche ich diese über codecs zu öffnen, bekomme ich einen Fehler. Oder habe ich dich falsch verstanden, und du meinst das einlesen an ganz anderer Stelle?
@Hyperion: Mir ist schon klar, dass Unicode nicht gleich utf-8 ist. Mein Problem ist ja (glaube ich zumindest), dass ich eine Zeile in Unicode habe und die andere in utf-8 kodiert ist. Allerdings ist mein Problem, dass ich es nicht schaffe, eine in das jeweils andere umzuwandeln. Zur besseren Erläuterung werde ich mal gucken, dass ich ein wenig Code hier reinstelle. Allerdings kann dies ein bisschen dauern, aber ich melde mich dann wieder.
Noch eine Frage an alle: Gemeckert wird generell nur, dass das Zeichen "0xFC" nicht umzuwandeln ist. Weiß jemand, was das ist. Ich habe irgendwo gelesen, dass das "ü" ist. Bei "ä" und "ö" wird nichts beanstandet.
Vielen Dank aber schonmal für eure Hilfe, ich melde mich später dann nochmal mit ein bisschen Code wieder
@deets: Bei welchem Einlesen meinst du? Die Textdatei mit den Daten aus der Exceltabelle (Exceltext.txt) öffne ich über das codecs-Modul, die andere Textdatei (Text_neu.txt) kann ich nur über die BIF open öffnen. Versuche ich diese über codecs zu öffnen, bekomme ich einen Fehler. Oder habe ich dich falsch verstanden, und du meinst das einlesen an ganz anderer Stelle?
@Hyperion: Mir ist schon klar, dass Unicode nicht gleich utf-8 ist. Mein Problem ist ja (glaube ich zumindest), dass ich eine Zeile in Unicode habe und die andere in utf-8 kodiert ist. Allerdings ist mein Problem, dass ich es nicht schaffe, eine in das jeweils andere umzuwandeln. Zur besseren Erläuterung werde ich mal gucken, dass ich ein wenig Code hier reinstelle. Allerdings kann dies ein bisschen dauern, aber ich melde mich dann wieder.
Noch eine Frage an alle: Gemeckert wird generell nur, dass das Zeichen "0xFC" nicht umzuwandeln ist. Weiß jemand, was das ist. Ich habe irgendwo gelesen, dass das "ü" ist. Bei "ä" und "ö" wird nichts beanstandet.
Vielen Dank aber schonmal für eure Hilfe, ich melde mich später dann nochmal mit ein bisschen Code wieder

- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Ja dann ist es doch ziemlich klar, dass da ein Problem besteht - vermutlich stimmt das Encoding der Datei nicht mit dem überein, welches Du bei ``codecs.open`` angibst. Allerdings ist das eher eine (starke) Vermutung, nachdem wir keinen Code und keine exakte Fehlermeldung vorliegen haben.TweetMiner1 hat geschrieben: @deets: ... die andere Textdatei (Text_neu.txt) kann ich nur über die BIF open öffnen. Versuche ich diese über codecs zu öffnen, bekomme ich einen Fehler.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
-
- User
- Beiträge: 12
- Registriert: Donnerstag 26. Januar 2012, 08:35
Also, hier ist mal ein wenig Code von mir, ist aber etwas vereinfacht, ich habe hoffentlich nichts wesentliches vergessen:
In dem Vergleich der beiden Textdateien wird immer in den else-Block gesprungen, die Zeilen sind also nicht gleich. Im else-Block werden die beiden Dateien dann in der Shell geprinted und sehen genau gleich aus. Aber das Problem ist, dass sie halt nur gleich aussehen.
@deets: Warum ich die nur über die BIF open öffnen kann weiß ich nicht. Wenn ich es über codecs probiere bekomme ich folgende Fehlermeldung:
@Hyperion: Und wie finde ich das heraus, bzw. wie oder was ändere ich?
So, hoffe der Code konnte ein wenig weiterhelfen. Trotzdem schon mal vielen Dank für eure Mühen!
Code: Alles auswählen
# Öffnen der Exceldateien:
workbook = xlrd.open_workbook('Exceldatei.xls')
Excel_sheet = workbook.sheet_by_index(2)
excel_outdata = open("Exceltext.txt", "w")
# Auslesen der Excelzellen
i = 0
EXCELZEILEN_BESCHRIEBEN = 600
while i < EXCELZEILEN_BESCHRIEBEN:
text_excel = Excel_sheet.cell(i, 3).value
print >> excel_outdata, text.encode("utf-8")
i = i + 1
excel_outdata.close()
# Öffnen der Textdatei:
Text = open("Text.txt", "r")
text_outdata = open("Text_neu.txt", "w")
#Auslesen der Textdatei
for Zeile in Text:
text_text = Zeile.strip()
print >> text_outdata, text_text #Habe hier auch versucht, an text_text ein .encode dran zu hängen, dann bekomme ich nur eine Fehlermeldung
Text.close()
text_outdata.close()
#Auslesen und vergleichen der beiden neuen Textdateien:
Exceltext = codecs.open("Exceltext.txt", encoding="utf-8", mode="r")
for Excelzeile in Exceltext:
Text_bearbeitet = open("Text_neu.txt", "r")
for Textzeile in Text_bearbeitet:
if Excelzeile == Textzeile:
print "Die Zeilen sind gleich"
else:
print "Die Zeilen sind nicht gleich:"
print Excelzeile
print Textzeile
Text_bearbeitet.close()
@deets: Warum ich die nur über die BIF open öffnen kann weiß ich nicht. Wenn ich es über codecs probiere bekomme ich folgende Fehlermeldung:
Code: Alles auswählen
Traceback (most recent call last):
File "C:\Users\***\Desktop\***\Komplett.py", line 217, in <module>
Vergleiche()
File "C:\Users\***\Desktop\***\Komplett.py", line 187, in Vergleiche
for VB_Codezeile in VB_Code:
File "C:\Python27\lib\codecs.py", line 684, in next
return self.reader.next()
File "C:\Python27\lib\codecs.py", line 615, in next
line = self.readline()
File "C:\Python27\lib\codecs.py", line 530, in readline
data = self.read(readsize, firstline=True)
File "C:\Python27\lib\codecs.py", line 477, in read
newchars, decodedbytes = self.decode(data, self.errors)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xfc in position 38: invalid start byte
So, hoffe der Code konnte ein wenig weiterhelfen. Trotzdem schon mal vielen Dank für eure Mühen!
Der Fehler sieht halt so aus als ob du eben *NICHT* utf-8 in der Datei stehen hast. Das ist dein Problem - dem nun abzuhelfen, indem du einfach open verwendest, weil's nicht meckert, verlagert das Problem dann nur auf spaeter.
In der Summe sieht's einfach so aus, dass du nicht wirlich sauber schreibst & liest. Ueberpruef das nochmal alles ganz genau, dass da auch die richtigen UTF-8 kodierten Daten in den Dateien sind.
In der Summe sieht's einfach so aus, dass du nicht wirlich sauber schreibst & liest. Ueberpruef das nochmal alles ganz genau, dass da auch die richtigen UTF-8 kodierten Daten in den Dateien sind.
-
- User
- Beiträge: 12
- Registriert: Donnerstag 26. Januar 2012, 08:35
Du meinst also in der Textdatei, die ich ursprünglich einlese und wo ich dann die Zeilen draus in eine neue Textdatei speichere? Das könnte ich mir durchaus auch vorstellen, deshalb ja auch mein Frage, ob jemand weiß, was "0xfc" ist, da ja nur hier gemeckert wird.deets hat geschrieben:Der Fehler sieht halt so aus als ob du eben *NICHT* utf-8 in der Datei stehen hast. Das ist dein Problem - dem nun abzuhelfen, indem du einfach open verwendest, weil's nicht meckert, verlagert das Problem dann nur auf spaeter.
In der Summe sieht's einfach so aus, dass du nicht wirlich sauber schreibst & liest. Ueberpruef das nochmal alles ganz genau, dass da auch die richtigen UTF-8 kodierten Daten in den Dateien sind.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Steht da evtl. eine BOM am Anfang der Datei? Wenn ja, musst Du diese mal eleminieren, oder den enstprechenden Parameter in ``codecs.open`` angeben. Wie die Python Doku aber empfiehlt, sollte man bei UTF-8 Dateien keine BOM am Anfang stehen haben, weswegen Variante eins vorzuziehen ist.
Ansonsten liegt die Datei eben nicht im UTF-8 Format vor und Du musst eben das richtige Encoding angeben.
Ansonsten liegt die Datei eben nicht im UTF-8 Format vor und Du musst eben das richtige Encoding angeben.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
-
- User
- Beiträge: 12
- Registriert: Donnerstag 26. Januar 2012, 08:35
Ich habe langsam das Gefühl, ich komme dem Problem immer nähre dank euch!Hyperion hat geschrieben:Steht da evtl. eine BOM am Anfang der Datei? Wenn ja, musst Du diese mal eleminieren, oder den enstprechenden Parameter in ``codecs.open`` angeben. Wie die Python Doku aber empfiehlt, sollte man bei UTF-8 Dateien keine BOM am Anfang stehen haben, weswegen Variante eins vorzuziehen ist.
Ansonsten liegt die Datei eben nicht im UTF-8 Format vor und Du musst eben das richtige Encoding angeben.
Falls es hilft, die Datei Text.txt enthält VB-Code, könnte das mit dem BOM dann zutreffen (Habe ehrlich gesagt nicht wirklich eine Ahnung was BOM ist außer grade durch Wikipedia)?
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Du kannst mal in der Doku im Kapitel 7.8.2 (``coddecs``-Modul, unter der Tabelle) nachlesen, was es damit in Bezug auf utf-8 auf sich hat. Augenscheinlich ist die Sequenz aber ``0xef, 0xbb, 0xbf`` - also nicht das, was bei Dir auftritt.TweetMiner1 hat geschrieben: Falls es hilft, die Datei Text.txt enthält VB-Code, könnte das mit dem BOM dann zutreffen (Habe ehrlich gesagt nicht wirklich eine Ahnung was BOM ist außer grade durch Wikipedia)?
Insofern tippe ich einfach mal auf ein anderes Encoding. Hat Windows nicht dieses cp-1252 Dingens als Standard?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
-
- User
- Beiträge: 12
- Registriert: Donnerstag 26. Januar 2012, 08:35
Danke, das hat sehr geholfen, nun bekomme ich keine Warnungen oder Fehler mehr. Das Windows Encoding ist tatsächlich cp1252.Hyperion hat geschrieben:Du kannst mal in der Doku im Kapitel 7.8.2 (``coddecs``-Modul, unter der Tabelle) nachlesen, was es damit in Bezug auf utf-8 auf sich hat. Augenscheinlich ist die Sequenz aber ``0xef, 0xbb, 0xbf`` - also nicht das, was bei Dir auftritt.TweetMiner1 hat geschrieben: Falls es hilft, die Datei Text.txt enthält VB-Code, könnte das mit dem BOM dann zutreffen (Habe ehrlich gesagt nicht wirklich eine Ahnung was BOM ist außer grade durch Wikipedia)?
Insofern tippe ich einfach mal auf ein anderes Encoding. Hat Windows nicht dieses cp-1252 Dingens als Standard?
Mein Programm sagt mir zwar immer noch, dass die beiden Zeilen nicht gleich sein sollen, aber das Problem bekomme ich (hoffentlich) auch noch irgendwie hin.
Vielen Dank euch, ich bin erstaunt, wie schnell man hier so gute Ideen bekommt. Und das obwohl ihr ja nicht mal in mein Programm eingearbeitet seid! Top

- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Vielleicht sind da unterschiedliche Whitespaces das Problem? Lass Dir doch mal die ``repr``-Form ausgeben.TweetMiner1 hat geschrieben: Mein Programm sagt mir zwar immer noch, dass die beiden Zeilen nicht gleich sein sollen, aber das Problem bekomme ich (hoffentlich) auch noch irgendwie hin.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
-
- User
- Beiträge: 12
- Registriert: Donnerstag 26. Januar 2012, 08:35
Also ich benutze bei den Zeilen noch die .strip()-Funktion, somit dürften Whitespaces am Anfang oder Ende doch eigentlich kein Problem sein oder?Hyperion hat geschrieben:Vielleicht sind da unterschiedliche Whitespaces das Problem? Lass Dir doch mal die ``repr``-Form ausgeben.TweetMiner1 hat geschrieben: Mein Programm sagt mir zwar immer noch, dass die beiden Zeilen nicht gleich sein sollen, aber das Problem bekomme ich (hoffentlich) auch noch irgendwie hin.
Und wenn zwischendurch ein Leerzeichen oder so wäre, würde ich das doch sehen, wenn ich die Zeilen direkt untereinander stehen.
Aber ich werde deinen Tipp mal ausprobieren!
-
- User
- Beiträge: 12
- Registriert: Donnerstag 26. Januar 2012, 08:35
Upps, hab mich vertan, habe einmal die strip-Funktion vergessen, nachdem ich die zweite Textdatei neu eingelesen habe. Jetzt funktionierts!TweetMiner1 hat geschrieben:Also ich benutze bei den Zeilen noch die .strip()-Funktion, somit dürften Whitespaces am Anfang oder Ende doch eigentlich kein Problem sein oder?Hyperion hat geschrieben:Vielleicht sind da unterschiedliche Whitespaces das Problem? Lass Dir doch mal die ``repr``-Form ausgeben.TweetMiner1 hat geschrieben: Mein Programm sagt mir zwar immer noch, dass die beiden Zeilen nicht gleich sein sollen, aber das Problem bekomme ich (hoffentlich) auch noch irgendwie hin.
Und wenn zwischendurch ein Leerzeichen oder so wäre, würde ich das doch sehen, wenn ich die Zeilen direkt untereinander stehen.
Aber ich werde deinen Tipp mal ausprobieren!
Danke. Aber woher weißt du sowas alles?

- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Naja, Erfahrung - viele solcher kleinen nervigen Dinge hat jeder mal gelöst, andere hier im Forum schon zig Mal geselesen... also alles keine Hexerei oder MagieTweetMiner1 hat geschrieben: Danke. Aber woher weißt du sowas alles?

encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
-
- User
- Beiträge: 12
- Registriert: Donnerstag 26. Januar 2012, 08:35
Und ich dachte schon, es wäre genau eins von dem gewesen!Hyperion hat geschrieben:Naja, Erfahrung - viele solcher kleinen nervigen Dinge hat jeder mal gelöst, andere hier im Forum schon zig Mal geselesen... also alles keine Hexerei oder MagieTweetMiner1 hat geschrieben: Danke. Aber woher weißt du sowas alles?


Vielen Dank!
P.S. Muss ich das Thema irgendwie als gelöst oder so markieren?