Ich habe meinen Kopf noch nie vollständig um Kodierung und Dekodierung von Unicode in andere Formate (utf-8, utf-16, ascii usw.) gewickelt, aber ich habe eine Wand erreicht, die verwirrend und frustrierend ist. Was ich versuche zu tun, ist das Drucken von utf-8-Kartensymbolen (♠, ♥, ♦, ♣) von einem Python-Modul zu einer Windows-Konsole. Die Konsole, die ich verwende, ist git bash und ich benutze Console2 als Frontend. Ich habe unten eine Reihe von Ansätzen ausprobiert/gelesen und bisher hat nichts funktioniert. Lassen Sie mich wissen, ob das, was ich mache, möglich ist und wie es richtig gemacht wird.
Versuchen Sie dasselbe vom Python-Modul.
Wenn ich das .py ausführte, ist dies das Ergebnis.
print(u'♠')
UnicodeEncodeError: 'charmap' codec can't encode character '\u2660' in position 0: character maps to <undefined>
Versuch, ♠ ..__ zu codieren. Dadurch wird der in utf-8 codierte Unicode-Satz zurückgegeben, jedoch kein Spatensymbol.
text = '♠'
print(text.encode('utf-8'))
b'\xe2\x99\xa0'
Ich habe das Gefühl, einen Schritt zu verpassen oder den gesamten Kodierungs-/Dekodierungsprozess nicht zu verstehen. Ich habe this , this und this gelesen. Die letzte der Seiten schlägt vor, die Datei sys.stdout in den Code zu packen, aber in this wird die Verwendung von stdout nicht benötigt und zeigt mit dem Codecs-Modul auf eine andere Seite.
Ich bin so verwirrt! Ich finde, dass Qualitätsdokumentation zu diesem Thema schwer zu finden ist und hoffentlich jemand das klären kann. Jede Hilfe wird immer geschätzt!
Austin
Was ich versuche zu tun, ist das Drucken von utf-8-Kartensymbolen (♠, ♥, ♦, ♣) von einem Python-Modul zu einer Windows-Konsole
UTF-8 ist eine Byte-Kodierung von Unicode-Zeichen. ♥ ♥ ♦ ♣ sind Unicode-Zeichen, die in verschiedenen Kodierungen reproduziert werden können, und UTF-8 ist eine dieser Kodierungen. UTF-8 kann als UTF beliebige Unicode-Zeichen reproduzieren. Es gibt jedoch nichts spezifisch "UTF-8" an diesen Zeichen.
Andere Kodierungen, die die Zeichen reproduzieren können, sind Windows Codepage 850 und 437 , die Ihre Konsole bei einer westeuropäischen Installation von Windows wahrscheinlich verwendet. Sie können ♠ mit diesen Kodierungen drucken, verwenden jedoch nicht UTF-8, und Sie können keine anderen Unicode-Zeichen verwenden, die in UTF-8 verfügbar sind, jedoch außerhalb des Gültigkeitsbereichs dieser Codeseiten liegen.
print(u'♠')
UnicodeEncodeError: 'charmap' codec can't encode character '\u2660'
In Python 3 ist dies dasselbe wie bei dem print('♠')
-Test, den Sie oben durchgeführt haben. Es ist also etwas anders, wie Sie das Skript aufrufen, das diese print
enthält, im Vergleich zu Ihrem py -3.4
. Was gibt Ihnen sys.stdout.encoding
aus dem Skript?
Damit print
richtig funktioniert, müssen Sie sicherstellen, dass Python die richtige Kodierung verwendet. Wenn dies von den Terminaleinstellungen aus nicht ausreichend ist, müssen Sie PYTHONIOENCODING
tatsächlich auf cp437
setzen.
>>> text = '♠'
>>> print(text.encode('utf-8'))
b'\xe2\x99\xa0'
print
kann nur Unicode-Zeichenfolgen drucken. Bei anderen Typen, einschließlich der bytes
-Zeichenfolge, die sich aus der encode()
-Methode ergibt, wird die Literaldarstellung (repr
) des Objekts abgerufen. b'\xe2\x99\xa0'
schreibt ein Python-3-Byte-Literal, das ein UTF-8-codiertes ♠ enthält.
Wenn Sie die implizite Kodierung von print
in PYTHONIOENCODING umgehen und durch Ihre eigene ersetzen möchten, können Sie dies explizit tun:
>>> import sys
>>> sys.stdout.buffer.write('♠'.encode('cp437'))
Dies führt natürlich zu einer falschen Ausgabe für alle Konsolen, die keine Codepage 437 ausführen (z. B. nicht westeuropäische Installationen). Im Allgemeinen ist es für Apps, die das C stdio verwenden, wie Python, das Zuweisen von Nicht-ASCII-Zeichen an die Windows-Konsole zu unzuverlässig, um damit zu kämpfen.
Kodiere nicht in utf-8; stattdessen Unicode direkt drucken:
print(u'♠')
Standardmäßig zeigt die Konsole in Microsoft Windows nur 256 Zeichen (cp437 von " Codepage 437 ", der ursprüngliche IBM-PC 1981-erweiterte ASCII - Zeichensatz) an, wie Sie in Kommentaren sagen.
und auf der anderen Seite ist PYTHONIOENCODING
standardmäßig auf UTF-8
eingestellt. Ich denke, wenn Sie Unicode in Windows drucken möchten, müssen Sie sys.stdout.encoding
und PYTHONIOENCODING
miteinander ausrichten!
Beachten Sie auch, dass Sie beim Festlegen einer Kodierung für Ihre.py
-Datei diese für diesen Code einfach verwenden und das Standardsystemencoding
nicht ändern.
also etwas so machen:
import codecs
my_str='♠' # or something like my_str='\u05dd'
my_str.encode().decode('cp437')