Encode error, cp850.py, u0130

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
albminak
User
Beiträge: 2
Registriert: Mittwoch 5. August 2015, 13:33

Ich verwende die Windows Version von Python 3.4 und würde gern mit Hilfe des print commands den Wert eines Attributes anzeigen. Als Konsole verwende ich cmd.exe

Um unicode anzeigen zu können, führe ich zunächst folgenden Befehl in der Konsole aus:

Code: Alles auswählen

chcp 65001
Folgende JSON Anfrage liefert eine Liste mit 'Follower' Attributen von der Soundcloud API:

Code: Alles auswählen

client=soundcloud.Client(client_id='XXXXXXXXXXXX')
user_followers=client.get('/users/%d/followers' % user.id, limit=100, linked_partitioning=1)
Nun möchte ich für alle 'Follower' das Attribut 'city' anzeigen:

Code: Alles auswählen

for follower_item in user_followers.collection:
           print (follower_item[u'city'])
Ich erhalte folgende Fehlermeldung (nachdem bereits einige Werte korrekt angezeigt wurden):
File “C:\Python34\lib\encodings\cp850.py“, line 12, in encode return codecs.charmap_encode(input,errors,encoding_map)[0] UnicodeEncodeError: ‘charmap‘ codec can’t encode character ‘\u0130‘ in position 0: character maps to (undefined)
Wie lässt sich das Problem beheben? Bitte um Erklärung für einen Python Anfänger, danke!
BlackJack

@albminak: Python geht anscheinend davon aus das die Ausgabe CP850-kodiert werden soll.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

albminak hat geschrieben:

Code: Alles auswählen

for follower_item in user_followers.collection:
           print (follower_item[u'city'])
Zunächst: Wozu das "u" vor "city"? Wenn du Python 3 verwendest, dann sind in Anführungszeichen angegebene Strings immer automatisch Unicode. Oder geht es darum, dass der Code auch unter Python 2 laufen soll?

Und was den Fehler angeht: Da musst du möglicherweise das Encoding des Terminals mit angeben. Wie liegen die Werte des `follower_item`s denn vor? Wenn sie als Bytestrings vorliegen, dann würde ich folgendes anwenden:

Code: Alles auswählen

for item in user_followers.collection:
    print(item['city'].decode(sys.stdout.encoding))
BlackJack

@snafu: Genau das sollte `print()` eigentlich von selbst tun und `sys.stdout.encoding` ist dann laut Fehlermeldung 'cp850' und die Stadt enthält ein Zeichen das in dieser Kodierung nicht vorhanden ist. Oder die Ausgabe geht gar nicht direkt an das Terminal sondern wird beispielsweise in ``more`` gepiped oder in eine Datei umgeleitet. Dann wäre das kein Problem von Python, denn in dem Falle ist es unmöglich die richtige Kodierung zu raten und Python 3 nimmt dann die ”Systemkodierung”. Da finde ich Python 2 besser, das nimmt ASCII und fällt damit viel schneller auf die Schnauze, was dem Benutzer/Programmierer darauf hinweist das da nicht sauber und robust programmiert wurde sowie etwas ausserhalb von der halbwegs sicheren ASCII-Untermenge geschrieben werden soll.

Das es ein *en*code-Fehler mit einem Unicode-Zeichen ausserhalb von ASCII ist, legt auch nahe das die API bereits eine Unicode-Zeichenkette liefert, man also nichts mehr dekodieren muss.

Der Stadtname scheint ein 'İ' (grosses I mit einem Punkt darüber) zu enthalten:

Code: Alles auswählen

In [1]: print u'\u0130'
İ
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mir war gestern Nacht offenbar nicht mehr bewusst, dass Pythons `print`-Funktion schon genau das tut, was ich beschrieben habe. Oder besser gesagt: Es wandelt Unicode-Strings selbständig unter Nutzung einer geratenen Kodierung in Bytestrings um. Dieses Raten basiert in erster Linie auf der Kodierung des Ausgabe-Streams, also z.B. auf `sys.stdout.encoding`.

Man hätte auch gesehen, dass es sich wohl um Unicode-Strings handelt, da bei Bytestrings ein "b" vorangestellt wird, welches von Python auch bei `print()` mit angezeigt wird. Bitte meinen vorherigen Beitrag daher komplett vergessen. ;)
albminak
User
Beiträge: 2
Registriert: Mittwoch 5. August 2015, 13:33

Danke für eure Antworten!!

Leider ist mir nicht klar, wie ich das Problem beheben kann. Könnte es evtl. helfen eine andere Konsole zu verwenden?

Ich bin Laie auf diesem Gebiet und wäre um jede Hilfestellung zur Problemlösung dankbar :)
BlackJack

@albminak: Beschäftige Dich mit Kodierungen — da kommt man als Programmierer heutzutage nicht wirklich drum herum — und dann kodiere die Ausgaben entsprechend selber. Am besten machst Du die Kodierung als Option, so dass der Benutzer sich aussuchen kann in welcher Kodierung die Ausgabe getätigt wird. Ich persönlich verwende ganz gerne UTF8 als Defaultkodierung, weil damit ”alles” kodiert werden kann.
Antworten