Umlaute "wiederherstellen"

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
heiliga horsd

Moin,

ich habe ein total simples Problem und stell mich gerade mal wieder saublöd an -.-

Ich habe einen Generator, der liefert mir Strings (Namen von Freunden, aus der Facebook-API abgerufen und in eine Textdatei kopiert).

Leider sind die Umlaute drauf gegangen, d.h. aus "Ronja Räubertochter" wurde "Ronja R\u00e4ubertochter"

Wie bekomm ich die Umlaute zurück? Habs mit name.encode('utf-8') funktioniert, hat leider nicht funktioniert. urllib.parse.unquote() hat leider auch nicht die gewünschten Ergebnisse geliefert.

Ich weiß, die Lösung ist sicherlich total einfach, ich steh aber total auf dem Schlauch und hoffe jemand kann mir den richtigen Tipp geben!


Gruß heiliga horsd
Zuletzt geändert von heiliga horsd am Dienstag 12. Juni 2012, 19:30, insgesamt 1-mal geändert.
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

heiliga horsd hat geschrieben:Leider sind die Umlaute drauf gegangen, d.h. aus "Ronja Räubertochter" wurde "Ronja R\u00e4ubertochter"

Wie bekomm ich die Umlaute zurück? Habs mit name.encode('utf-8') funktioniert, hat leider nicht funktioniert.
encode kann nicht richtig sein, da das ganze ja bereits codiert ist. Den Hinweis zum passenden Codec findest du im Manual zum codecs-Modul.

Code: Alles auswählen

>>> print 'Ronja R\u00e4ubertochter'.decode('unicode_escape')
Ronja Räubertochter
heiliga horsd

File "C:\Users\**\Desktop\Facebook_Friends.py", line 8, in clean_data
yield (element.lstrip(' ').decode('unicode_escape'))
AttributeError: 'str' object has no attribute 'decode'
Liegt's evtl. an Python 3 oder mache ich einen anderen dummen Fehler??

edit: Codecs ist importiert, in der Doku steht, dass ich ein Codec-Objekt brauche, du hast es aber irgendwie auch "ohne" geschafft?!
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

heiliga horsd hat geschrieben:Liegt's evtl. an Python 3 oder mache ich einen anderen dummen Fehler??

Code: Alles auswählen

Python 3.2.3rc2 (default, Mar 21 2012, 05:47:04) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print(b'Ronja R\u00e4ubertochter'.decode('unicode_escape'))
Ronja Räubertochter
Ja, denn Python 3 Strings kann man nicht dekodieren, da sie nicht kodiert sind. Bytestrings (was Strings in Python2 im Grunde waren) dagegen schon, darum das `b' vor dem Stringliteral.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@heiliga horsd:
Zeig doch mal die repr()-Ausgabe des Strings, dann wird klarer, ob da was im Argen liegt. Falls oben das die repr()-Version ist, sollte das doch so richtig sein, vgl. hierzu unter Python 2 mit u'':

Code: Alles auswählen

>>> print u'Ronja R\u00e4ubertochter'
Ronja Räubertochter
Unter Python 3 sollte hier der Umlaut erscheinen:

Code: Alles auswählen

print('Ronja R\u00e4ubertochter') # --> Ronja Räubertochter
heiliga horsd

Die repr-Version:

Code: Alles auswählen

'Ronja R\\u00e4ubertochter\n'

Code: Alles auswählen

def clean_data(data):
    for element in data:
        yield (bytes(element.lstrip(' ')).decode('unicode_codec'))

Code: Alles auswählen

File "C:\Users\**\Desktop\Facebook_Friends.py", line 8, in clean_data
    yield (bytes(element.lstrip(' ')).decode('unicode_codec'))
TypeError: string argument without an encoding
Die Daten kommen aus ner Datei und sollen da auch wieder zurück, aber ich will halt diese hässlichen Umlaute und die ganzen Leerzeichen vor den Einträgen los werden.

Gruß heilia horsd
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@heiliga horsd: Du hast es irgendwie nicht ganz verstanden. Deine Zeichenkette liegt bereits in einer Form vor, die nicht dekodiert werden kann. Mach doch mal ein `print(name)`. Dann siehst du, dass der String bereits in der gewünschten Form vorliegt.
heiliga horsd

Kommt drauf an, was gewünschte Form bedeutet - auch bei print(name) werden mir die Umlaute nicht angezeigt. :(
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

heiliga horsd hat geschrieben:

Code: Alles auswählen

File "C:\Users\**\Desktop\Facebook_Friends.py", line 8, in clean_data
    yield (bytes(element.lstrip(' ')).decode('unicode_codec'))
TypeError: string argument without an encoding
Ich habe Python 3 jetzt nicht zum Testen hier, aber ich versuche mal eine Analyse.

element bzw element.lstrip() ist ein String-Objekt (also Unicode). Du versuchst das jetzt in bytes-Objekt zu verwandeln. Dafür scheint ein Encoding gebraucht zu werden (der zweite Parameter von bytes) das du hier nicht angibst. Versuch es doch mal mit dem ASCII-Codec.
heiliga horsd

Tut mir Leid aber ich blicke inzwischen bei dem ganzen decoding / encoding Zeug gar nicht mehr durch... werds wohl per Hand mit Suchen & Ersetzen machen, Danke trotzdem an alle!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Was genau ist Dir denn unklar? Schau doch mal in meiner Sig den dritten Link an; da wird das Encoding-"Problem" für Python3 besprochen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
heiliga horsd

Hyperion hat geschrieben:Was genau ist Dir denn unklar? Schau doch mal in meiner Sig den dritten Link an; da wird das Encoding-"Problem" für Python3 besprochen.
Warum mein String anscheinend bereits Unicode-Kodiert ist, ich jedoch trotzdem so Escapes drin hab. Kann ja nicht sein, dass ich das zuerst zu bytes und dann wieder zu Unicode machen muss. Bis jetzt hat nichts funktioniert und Google ist mir auch nicht wirklich eine große Hilfe...
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

In Python3 wird automatisch dekodiert, sofern du die Datei nicht binaer oeffnest. Was du also eigentlich machen willst: Die Datei mit einem anderen Encoding oeffnen, also

Code: Alles auswählen

open(fname, encoding='unicode_escape')
heiliga horsd

Wow hat plötzlich alles funktioniert! Vielen Dank! Mich würde jetzt nur noch interessieren, welches Encoding Python beim Öffnen als default nimmt.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Manchmal hilft es ja einfach die Dokumentation zu lesen:
http://docs.python.org/py3k/library/functions.html#open hat geschrieben:encoding is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform dependent (whatever locale.getpreferredencoding() returns), but any encoding supported by Python can be used. See the codecs module for the list of supported encodings.
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Und genau deshalb gibt man das Encoding beim Schreiben explizit an.
heiliga horsd

cofi hat geschrieben:Manchmal hilft es ja einfach die Dokumentation zu lesen:
http://docs.python.org/py3k/library/functions.html#open hat geschrieben:encoding is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform dependent (whatever locale.getpreferredencoding() returns), but any encoding supported by Python can be used. See the codecs module for the list of supported encodings.
Stimmt, RTFM hätte ich mir denken können - leider fehlt mir bei dem Kodierungszeug noch ein wenig der Überblick in der Doku, aber ich denke das kommt mit der Zeit.

@/me: Danke, wusste ich nicht. Werd ich mir auf jeden Fall merken!
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

heiliga horsd hat geschrieben:Stimmt, RTFM hätte ich mir denken können - leider fehlt mir bei dem Kodierungszeug noch ein wenig der Überblick in der Doku, aber ich denke das kommt mit der Zeit.
Eins muss dir auf jeden Fall klar sein. Strings im Speicher sind Unicode-Strings. Unicode ist ein Konzept und nicht die Art und Weise wie ein Zeichen im Speicher aufgebaut ist. Aus diesem Grund kannst du auch keine Daten als Unicode speichern. Du kannst aber ein Encoding wie UTF-8 verwenden um Unicode-Strings zu speichern. In der Datei hast du dann kein Unicode, sondern einen UTF-8-codierten String. Beim Wiedereinlesen bekommst du im Speicher wieder einen Unicode-String. Dazu musst du allerdings beim Einlesen (bzw. beim Öffnen der Datei) angeben, welches Encoding dafür verwendet werden soll. Hast du Daten als UTF-8 gespeichert, dann solltest du sie auch mit UTF-8-Codierung wieder einlesen. Andere Formate wie EBCDIC würden einfach Datenmüll ergeben - wenn es denn überhaupt funktionierte.

Bitte merken
Von Unicode nach woanders hin: encode()
Von woanders nach Unicode: decode()
heiliga horsd

Super Erklärung, Danke!

Ich werd mich mal wenn ich demnächst Zeit finde wohl noch ein bisschen damit befassen - läuft einem ja immer wieder über den Weg...

Problem gelöst,
Gruß Heiliga Horsd
Antworten