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



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



Edit: Я использую Python 2.5.





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



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

686   13  

13 ответов:

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

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

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


я UnicodeEncodeError: 'charmap' codec can't encode character... ошибка.

ошибка означает, что Unicode символы, которые вы пытаетесь напечатать, не могут быть представлены с помощью текущего (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 должен использоваться, как предложено в @Дайра Хопвуда!--19-->. Он может быть вызван прозрачно, т. е. вам не нужно и не следует изменять свои скрипты, если вы используете win-unicode-console пакета:

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

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

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

если достаточно заменить все не поддающиеся кодированию символы на ? в вашем случае, то вы могли бы установить PYTHONIOENCODING envvar:

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,

на данный момент я просто хотел sthg, что означало бы, что моя программа не рухнет, и что я понял ... а также который не включал импорт слишком много экзотических модулей (в частности, я использую Jython, поэтому в половине случаев модуль Python на самом деле не является доступный.)

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

НБ "пиар" - это короче, чем "печать" (и совсем немного короче, чем "safeprint")...!

для 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 (я помещаю его под /usr / lib/python2.5 / site-packages, но это отличается от Win - это c:\python\lib\site-packages или что-то), со следующим содержанием:

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

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

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

Edit: дополнительная информация может быть найдена в отличном погружении в Python book

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

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

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

TL; DR:

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

Я сам столкнулся с этим, работая над ботом Twitch chat (IRC). (В Python 2.7 последний)

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

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

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

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

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

. Ответ ниже приближается к выполнению просьбы Сулака.

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

в место из:    print(text)
    замена:     print(str(text).encode('utf-8'))

вместо того, чтобы выдавать исключение, Python теперь отображает непечатаемые символы Юникода как \xNN hex-кодов, например:

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

вместо

Halmalo n'était plus qu'un point noir

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

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

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

chcp 65001 & set PYTHONIOENCODING=utf-8

Comments

    Ничего не найдено.