Frage

Wenn ich versuche, eine Unicode-Zeichenfolge in einer Windows-Konsole zu drucken, erhalte ich eine Fehlermeldung UnicodeEncodeError: 'charmap' codec can't encode character .... Fehler.Ich gehe davon aus, dass dies daran liegt, dass die Windows-Konsole keine Nur-Unicode-Zeichen akzeptiert.Was ist der beste Weg, dies zu umgehen?Gibt es eine Möglichkeit, Python automatisch drucken zu lassen? ? statt in dieser Situation zu scheitern?

Bearbeiten: Ich verwende Python 2.5.


Notiz: @LasseV.Karlsens Antwort mit dem Häkchen ist irgendwie veraltet (aus dem Jahr 2008).Bitte gehen Sie mit den untenstehenden Lösungen/Antworten/Vorschlägen vorsichtig um!!

@JFSebastian Antwort ist ab heute (6. Januar 2016) relevanter.

War es hilfreich?

Lösung

Notiz: Diese Antwort ist irgendwie veraltet (aus dem Jahr 2008).Bitte verwenden Sie die untenstehende Lösung mit Vorsicht!!


Hier ist eine Seite, die das Problem und eine Lösung detailliert beschreibt (durchsuchen Sie die Seite nach dem Text). Einbinden von sys.stdout in eine Instanz):

PrintFails – Python-Wiki

Hier ist ein Codeauszug von dieser Seite:

$ python -c 'import sys, codecs, locale; print sys.stdout.encoding; \
    sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); \
    line = u"\u0411\n"; print type(line), len(line); \
    sys.stdout.write(line); print line'
  UTF-8
  <type 'unicode'> 2
  Б
  Б

  $ python -c 'import sys, codecs, locale; print sys.stdout.encoding; \
    sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); \
    line = u"\u0411\n"; print type(line), len(line); \
    sys.stdout.write(line); print line' | cat
  None
  <type 'unicode'> 2
  Б
  Б

Auf dieser Seite gibt es noch einige weitere Informationen, die unbedingt gelesen werden sollten.

Andere Tipps

Aktualisieren: Python 3.6 implementiert PEP 528:Ändern Sie die Codierung der Windows-Konsole in UTF-8: Die Standardkonsole unter Windows akzeptiert jetzt alle Unicode-Zeichen. Intern verwendet es dieselbe Unicode-API wie Die win-unicode-console Paket unten erwähnt. print(unicode_string) sollte jetzt einfach funktionieren.


Ich bekomme ein UnicodeEncodeError: 'charmap' codec can't encode character... Fehler.

Der Fehler bedeutet, dass Unicode-Zeichen, die Sie drucken möchten, nicht mit dem aktuellen (chcp) Konsolenzeichenkodierung.Bei der Codepage handelt es sich häufig um eine 8-Bit-Kodierung, z cp437 das kann nur ~0x100 Zeichen aus ~1M Unicode-Zeichen darstellen:

>>> u"\N{EURO SIGN}".encode('cp437')
Traceback (most recent call last):
...
UnicodeEncodeError: 'charmap' codec can't encode character '\u20ac' in position 0:
character maps to 

Ich gehe davon aus, dass dies daran liegt, dass die Windows-Konsole keine Nur-Unicode-Zeichen akzeptiert.Was ist der beste Weg, dies zu umgehen?

Die Windows-Konsole akzeptiert Unicode-Zeichen und kann diese sogar anzeigen (nur BMP). wenn die entsprechende Schriftart konfiguriert ist. WriteConsoleW() Die API sollte wie in vorgeschlagen verwendet werden @Daira Hopwoods Antwort.Es kann transparent aufgerufen werden, d. h. Sie müssen und sollten Ihre Skripte nicht ändern, wenn Sie sie verwenden win-unicode-console Paket:

T:\> py -mpip install win-unicode-console
T:\> py -mrun your_script.py

Sehen Was hat es mit Python 3.4, Unicode, verschiedenen Sprachen und Windows auf sich?

Gibt es eine Möglichkeit, Python automatisch a zu drucken lassen ? statt in dieser Situation zu scheitern?

Wenn es ausreicht, alle nicht kodierbaren Zeichen durch zu ersetzen ? in Deinem Fall könntest Du das dann einstellen PYTHONIOENCODING envvar:

T:\> set PYTHONIOENCODING=:replace
T:\> python3 -c "print(u'[\N{EURO SIGN}]')"
[?]

In Python 3.6+ ist die durch angegebene Kodierung PYTHONIOENCODING envvar wird für interaktive Konsolenpuffer ignoriert, es sei denn PYTHONLEGACYWINDOWSIOENCODING envvar ist auf eine nicht leere Zeichenfolge festgelegt.

Trotz der anderen plausibel klingenden Antworten, die eine Änderung der Codepage auf 65001 vorschlagen, ist dies der Fall funktioniert nicht.(Ändern Sie außerdem die Standardkodierung mit sys.setdefaultencoding Ist keine gute Idee.)

Sehen diese Frage für Details und Code, der funktioniert.

Wenn Sie nicht daran interessiert sind, eine zuverlässige Darstellung der schlechten Zeichen zu erhalten, können Sie so etwas verwenden (bei Python >= 2.6, einschließlich 3.x):

from __future__ import print_function
import sys

def safeprint(s):
    try:
        print(s)
    except UnicodeEncodeError:
        if sys.version_info >= (3,):
            print(s.encode('utf8').decode(sys.stdout.encoding))
        else:
            print(s.encode('utf8'))

safeprint(u"\N{EM DASH}")

Die fehlerhaften Zeichen in der Zeichenfolge werden in eine Darstellung umgewandelt, die von der Windows-Konsole gedruckt werden kann.

Mit dem folgenden Code wird Python auch unter Windows als UTF-8 an die Konsole ausgegeben.

Die Konsole zeigt die Zeichen unter Windows 7 gut an, unter Windows XP jedoch nicht, aber zumindest funktioniert es und, was am wichtigsten ist, Sie erhalten auf allen Plattformen eine konsistente Ausgabe Ihres Skripts.Sie können die Ausgabe in eine Datei umleiten.

Der folgende Code wurde mit Python 2.6 unter Windows getestet.


#!/usr/bin/python
# -*- coding: UTF-8 -*-

import codecs, sys

reload(sys)
sys.setdefaultencoding('utf-8')

print sys.getdefaultencoding()

if sys.platform == 'win32':
    try:
        import win32console 
    except:
        print "Python Win32 Extensions module is required.\n You can download it from https://sourceforge.net/projects/pywin32/ (x86 and x64 builds are available)\n"
        exit(-1)
    # win32console implementation  of SetConsoleCP does not return a value
    # CP_UTF8 = 65001
    win32console.SetConsoleCP(65001)
    if (win32console.GetConsoleCP() != 65001):
        raise Exception ("Cannot set console codepage to 65001 (UTF-8)")
    win32console.SetConsoleOutputCP(65001)
    if (win32console.GetConsoleOutputCP() != 65001):
        raise Exception ("Cannot set console output codepage to 65001 (UTF-8)")

#import sys, codecs
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
sys.stderr = codecs.getwriter('utf8')(sys.stderr)

print "This is an Е乂αmp١ȅ testing Unicode support using Arabic, Latin, Cyrillic, Greek, Hebrew and CJK code points.\n"

Wie die Antwort von Giampaolo Rodolà, aber noch schmutziger:Ich habe wirklich, wirklich vor, (bald) viel Zeit damit zu verbringen, das gesamte Thema der Codierungen und ihre Anwendung auf Windoze-Konsolen zu verstehen.

Im Moment wollte ich nur etwas, was bedeuten würde, dass mein Programm NICHT ABSTURZT, und was ich verstanden habe ...und was auch nicht den Import zu vieler exotischer Module erforderte (insbesondere verwende ich Jython, sodass sich herausstellt, dass ein Python-Modul in der Hälfte der Fälle tatsächlich nicht verfügbar ist).

def pr(s):
    try:
        print(s)
    except UnicodeEncodeError:
        for c in s:
            try:
                print( c, end='')
            except UnicodeEncodeError:
                print( '?', end='')

Hinweis: „pr“ ist kürzer zu tippen als „print“ (und um einiges kürzer zu tippen als „safeprint“) ...!

Geben Sie einfach diesen Code in die Befehlszeile ein, bevor Sie das Python-Skript ausführen:

chcp 65001 & set PYTHONIOENCODING=utf-8

Versuchen Sie für Python 2:

print unicode(string, 'unicode-escape')

Versuchen Sie für Python 3:

import os
string = "002 Could've Would've Should've"
os.system('echo ' + string)

Oder versuchen Sie es mit win-unicode-console:

pip install win-unicode-console
py -mrun your_script.py

Die Ursache Ihres Problems ist NICHT Die Win-Konsole ist nicht bereit, Unicode zu akzeptieren (da sie dies tut, da ich standardmäßig Win2k vermute).Es handelt sich um die Standard-Systemkodierung.Probieren Sie diesen Code aus und sehen Sie, was er Ihnen bringt:

import sys
sys.getdefaultencoding()

Wenn es ASCII besagt, gibt es Ihre Sache ;-) Sie müssen eine Datei namens Sitecustomize.py erstellen und sie unter Python-Pfad setzen (ich habe sie unter /usr/lib/python2.5/Site-Packages gestellt, aber das ist unterschiedlich auf Win - Es ist C: Python lib Site -Packages oder so) mit dem folgenden Inhalt:

import sys
sys.setdefaultencoding('utf-8')

und vielleicht möchten Sie auch die Kodierung in Ihren Dateien angeben:

# -*- coding: UTF-8 -*-
import sys,time

Bearbeiten:Weitere Informationen finden Sie hier In ausgezeichnetem Zustand ist das Buch „Dive into Python“.

TL;DR:

print(yourstring.encode('ascii','replace'));

Ich bin selbst darauf gestoßen, als ich an einem Twitch-Chat-Bot (IRC) gearbeitet habe.(Python 2.7 spätestens)

Ich wollte Chatnachrichten analysieren, um zu antworten ...

msg = s.recv(1024).decode("utf-8")

sondern drucken Sie sie auch sicher in einem für Menschen lesbaren Format auf der Konsole aus:

print(msg.encode('ascii','replace'));

Dadurch wurde das Problem mit dem Bot-Werfen behoben UnicodeEncodeError: 'charmap' Fehler und ersetzte die Unicode-Zeichen durch ?.

Irgendwie verwandt mit der Antwort von J.F.Sebastian, aber direkter.

Wenn dieses Problem beim Drucken auf der Konsole/dem Terminal auftritt, gehen Sie wie folgt vor:

>set PYTHONIOENCODING=UTF-8

Python 3.6 Windows7:Es gibt mehrere Möglichkeiten, Python zu starten. Sie können die Python-Konsole (auf der sich ein Python-Logo befindet) oder die Windows-Konsole (auf der cmd.exe steht) verwenden.

Ich konnte in der Windows-Konsole keine UTF8-Zeichen drucken.Beim Drucken von utf-8-Zeichen erhalte ich folgende Fehlermeldung:

OSError: [winError 87] The paraneter is incorrect 
Exception ignored in: (_io-TextIOwrapper name='(stdout)' mode='w' ' encoding='utf8') 
OSError: [WinError 87] The parameter is incorrect 

Nachdem ich versucht hatte, die obige Antwort nicht zu verstehen, stellte ich fest, dass es sich nur um ein Einstellungsproblem handelte.Klicken Sie mit der rechten Maustaste oben im CMD-Konsolenfenster auf die Registerkarte font Ich habe mich für die Lucida-Konsole entschieden.

James Sulak fragte:

Gibt es eine Möglichkeit, dass Python automatisch ein druckt?statt in dieser Situation zu scheitern?

Andere Lösungen empfehlen, dass wir versuchen, die Windows-Umgebung zu ändern oder die von Python zu ersetzen print() Funktion.Die folgende Antwort kommt der Erfüllung von Sulaks Bitte näher.

Unter Windows 7 kann Python 3.5 dazu gebracht werden, Unicode zu drucken, ohne ein auszulösen UnicodeEncodeError wie folgt:

Anstelle von:print(text)
Ersatz: print(str(text).encode('utf-8'))

Anstatt eine Ausnahme auszulösen, zeigt Python jetzt nicht druckbare Unicode-Zeichen als an \xNN Hex-Codes, z.B.:

  Halmalo n\xe2\x80\x99\xc3\xa9tait plus qu\xe2\x80\x99un point noir

Anstatt

  Halmalo n’était plus qu’un point noir

Zugegeben, Letzteres ist vorzuziehen ceteris paribus, aber ansonsten ist Ersteres für Diagnosemeldungen völlig korrekt.Da Unicode als literale Bytewerte angezeigt wird, kann ersteres auch bei der Diagnose von Codierungs-/Decodierungsproblemen hilfreich sein.

Notiz: Der str() Der obige Anruf ist erforderlich, da sonst encode() bewirkt, dass Python ein Unicode-Zeichen als Zahlentupel ablehnt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top