Python, Unicode и консоль Windows
когда я пытаюсь напечатать строку Unicode в консоли Windows, я получаю UnicodeEncodeError: 'charmap' codec can't encode character .... ошибка. Я предполагаю, что это связано с тем, что консоль Windows не принимает только символы Юникода. Какой лучший способ обойти это? Есть ли способ заставить Python автоматически печатать ? вместо того, чтобы потерпеть неудачу в этой ситуации?
Edit: Я использую Python 2.5.
Примечание: @LasseV.Ответ Карлсена с галочкой вроде устарел (от 2008). Пожалуйста, используйте решения/ответы/предложения ниже с осторожностью!!
@JFSebastian ответ более актуален на сегодняшний день (6 января 2016 года).
13 ответов:
Примечание: этот ответ является своего рода устаревшим (с 2008 года). Пожалуйста, используйте Решение ниже с осторожностью!!
вот страница, которая подробно описывает проблему и решение (поиск страницы для текста обертывание sys.stdout в экземпляре):
вот фрагмент кода с этой страницы:
$ 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?
есть ли способ я могу сделать Питон автоматически печатать
?вместо того, чтобы потерпеть неудачу в этой ситуации?если достаточно заменить все не поддающиеся кодированию символы на
?в вашем случае, то вы могли бы установитьPYTHONIOENCODINGenvvar:T:\> set PYTHONIOENCODING=:replace T:\> python3 -c "print(u'[\N{EURO SIGN}]')" [?]в Python 3.6+, кодировка, указанная
PYTHONIOENCODINGenvvar игнорируется для буферов интерактивной консоли, еслиPYTHONLEGACYWINDOWSIOENCODINGenvvar устанавливается в непустую строку.
несмотря на другие правдоподобно звучащие ответы, которые предлагают изменить кодовую страницу на 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,timeEdit: дополнительная информация может быть найдена в отличном погружении в 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