Вопрос

Когда я пытаюсь напечатать строку Unicode в консоли Windows, я получаю UnicodeEncodeError: 'charmap' codec can't encode character .... ошибка.Я предполагаю, что это связано с тем, что консоль Windows не принимает символы только Юникода.Какой лучший способ обойти это?Есть ли способ заставить Python автоматически печатать ? вместо того, чтобы потерпеть неудачу в этой ситуации?

Редактировать: Я использую Python 2.5.


Примечание: Ответ @LasseV.Karlsen с галочкой устарел (с 2008 года).Пожалуйста, используйте приведенные ниже решения/ответы/предложения с осторожностью!

@JFSebastian ответ более актуален на сегодняшний день (6 января 2016 г.).

Это было полезно?

Решение

Примечание: Этот ответ устарел (с 2008 года).Пожалуйста, используйте решение ниже с осторожностью!


Вот страница с подробным описанием проблемы и решения (найдите на странице текст Обертывание sys.stdout в экземпляр):

PrintFails — Python Wiki

Вот отрывок кода с этой страницы:

$ 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
  Б
  Б

На этой странице есть дополнительная информация, которую стоит прочитать.

Другие советы

Обновлять: Питон 3.6 реализует ПКП 528:Измените кодировку консоли Windows на UTF-8.: консоль по умолчанию в Windows теперь принимает все символы Юникода. Внутри он использует тот же API Unicode, что и тот win-unicode-console пакет, упомянутый ниже. print(unicode_string) теперь должно просто работать.


я получаю UnicodeEncodeError: 'charmap' codec can't encode character... ошибка.

Эта ошибка означает, что символы Юникода, которые вы пытаетесь напечатать, не могут быть представлены с использованием текущего (chcp) кодировка символов консоли.Кодовая страница часто представляет собой 8-битную кодировку, например cp437 который может представлять только ~0x100 символов из ~1M символов Юникода:

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

Я предполагаю, что это связано с тем, что консоль Windows не принимает символы только Юникода.Какой лучший способ обойти это?

Консоль Windows принимает символы Юникода и даже может их отображать (только в формате BMP). если соответствующий шрифт настроен. WriteConsoleW() API следует использовать, как предложено в Ответ @Дайры Хопвуд.Его можно вызывать прозрачно, т. е. вам не нужно и не следует изменять свои сценарии, если вы используете win-unicode-console упаковка:

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

Видеть Как обстоят дела с Python 3.4, Unicode, другими языками и Windows?

Есть ли способ, которым я могу сделать Python автоматически распечатать ? вместо того, чтобы потерпеть неудачу в этой ситуации?

Если достаточно заменить все некодируемые символы на ? в вашем случае вы можете установить PYTHONIOENCODING окружение:

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

В Python 3.6+ кодировка, указанная PYTHONIOENCODING envvar игнорируется для буферов интерактивной консоли, если только PYTHONLEGACYWINDOWSIOENCODING envvar имеет значение непустой строки.

Несмотря на другие правдоподобные ответы, предлагающие изменить кодовую страницу на 65001, это не работает.(Кроме того, изменение кодировки по умолчанию с помощью sys.setdefaultencoding является не хорошая идея.)

Видеть этот вопрос подробности и код, который работает.

Если вы не заинтересованы в получении надежного представления плохих символов, вы можете использовать что-то вроде этого (работая с Python >= 2.6, включая 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}")

Неверные символы в строке будут преобразованы в представление, которое можно распечатать с консоли Windows.

Приведенный ниже код выведет вывод Python на консоль как UTF-8 даже в Windows.

Консоль будет хорошо отображать символы в Windows 7, но в Windows XP она не будет отображать их хорошо, но, по крайней мере, она будет работать, и, что наиболее важно, вы будете иметь согласованный вывод из вашего сценария на всех платформах.Вы сможете перенаправить вывод в файл.

Приведенный ниже код был протестирован на Python 2.6 в Windows.


#!/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"

Как ответ Джампаоло Родола, но еще более грязный:Я действительно, очень намерен потратить много времени (в ближайшее время) на понимание всей темы кодировок и того, как они применяются к консолям Windoze.

На данный момент мне просто хотелось чего-то, что означало бы, что моя программа НЕ ВЫРУШИТСЯ, и что я понял...а также который не требовал импорта слишком большого количества экзотических модулей (в частности, я использую Jython, поэтому в половине случаев модуль Python фактически оказывается недоступным).

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

Обратите внимание: «pr» набирается короче, чем «print» (и немного короче, чем «safeprint»)…!

Просто введите этот код в командной строке перед выполнением скрипта Python:

chcp 65001 & set PYTHONIOENCODING=utf-8

Для Python 2 попробуйте:

print unicode(string, 'unicode-escape')

Для Python 3 попробуйте:

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

Или попробуйте win-unicode-console:

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

Причина вашей проблемы в том НЕТ консоль Win не желает принимать Unicode (поскольку она это делает, поскольку, я думаю, Win2k по умолчанию).Это системная кодировка по умолчанию.Попробуйте этот код и посмотрите, что он вам даст:

import sys
sys.getdefaultencoding()

Если он говорит ASCII, есть ваша причина ;-) Вы должны создать файл с именем sitecustomize.py и поместить его под путь Python (я поместил его в /ср/lib/python2.5/site-packes, но это различено на Win - это C: python lib site -packages или что -то в этом роде), со следующим содержимым:

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

и, возможно, вы также захотите указать кодировку в своих файлах:

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

Редактировать:дополнительную информацию можно найти в отличной книге «Погружение в Python»

ТЛ;ДР:

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

Я сам столкнулся с этим, работая над чат-ботом Twitch (IRC).(Последняя версия Python 2.7)

Я хотел проанализировать сообщения чата, чтобы ответить...

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

но также безопасно выводить их на консоль в удобочитаемом формате:

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

Это исправило проблему с броском бота. UnicodeEncodeError: 'charmap' ошибки и заменил символы Юникода на ?.

Отчасти связано с ответом Дж.Ф.Себастьян, но более прямолинейно.

Если у вас возникла эта проблема при печати на консоль/терминал, сделайте следующее:

>set PYTHONIOENCODING=UTF-8

Python 3.6 windows7:Существует несколько способов запустить Python: использовать консоль Python (на которой есть логотип Python) или консоль Windows (на ней написано cmd.exe).

Я не мог напечатать символы utf8 в консоли Windows.Печать символов utf-8 вызывает у меня эту ошибку:

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 

После того, как я не смог понять ответ выше, я обнаружил, что это всего лишь проблема с настройками.Щелкните правой кнопкой мыши в верхней части окна консоли cmd на вкладке font выбрал консоль lucida.

Джеймс Сулак спросил:

Есть ли способ заставить Python автоматически печатать файл ?вместо того, чтобы потерпеть неудачу в этой ситуации?

Другие решения рекомендуют попытаться изменить среду Windows или заменить среду Python. print() функция.Ответ ниже приближается к выполнению просьбы Сулака.

В Windows 7 Python 3.5 можно заставить печатать Unicode, не создавая UnicodeEncodeError следующее:

На месте:print(text)
заменять: print(str(text).encode('utf-8'))

Вместо выдачи исключения Python теперь отображает непечатаемые символы Юникода как \xNN шестнадцатеричные коды, например:

  Халмало n\xe2\x80\x99\xc3\xa9tait плюс qu\xe2\x80\x99un point noir

Вместо

  Halmalo n’était plus qu’un point noir

Согласен, последнее предпочтительнее при прочих равных условиях, но в остальном первый вариант полностью точен для диагностических сообщений.Поскольку он отображает Юникод в виде буквальных значений байтов, первый может также помочь в диагностике проблем кодирования/декодирования.

Примечание: А str() вызов выше необходим, потому что в противном случае encode() заставляет Python отклонять символ Юникода как кортеж чисел.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top