Сведения о вопросе

Kirushaa

16:03, 1st July, 2020

Теги

python   unicode    

Python, Unicode и консоль Windows

Просмотров: 551   Ответов: 4

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

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


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

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



  Сведения об ответе

baggs

18:03, 1st July, 2020

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


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

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

>>> 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 не принимает только символы Unicode. Как лучше всего это обойти?

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

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

Смотрите, что происходит с Python 3.4, Unicode, разными языками и Windows?

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

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

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

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


  Сведения об ответе

fo_I_K

18:03, 1st July, 2020

Примечание: этот ответ несколько устарел (с 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
  Б
  Б

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


  Сведения об ответе

dumai

18:03, 1st July, 2020

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

Смотрите этот вопрос для получения подробной информации и кода, который действительно работает.


  Сведения об ответе

lourence

18:03, 1st July, 2020

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться