web-dev-qa-db-de.com

Wie kann man utf-8 mit Python 3.4 (Windows 8) auf die Konsole drucken?

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.

  • Stellen Sie sicher, dass die Konsole mit Utf-8-Zeichen umgehen kann .. Diese beiden Tests lassen mich glauben, dass die Konsole nicht das Problem ist.

enter image description here

  • 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

22
Austin A

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.

13
bobince

Kodiere nicht in utf-8; stattdessen Unicode direkt drucken:

print(u'♠')

Siehe wie man Unicode an die Windows-Konsole druckt .

2
jfs

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')
0
Kasrâmvd