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

голоса
104

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

Изменить: Я использую Python 2.5.


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

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

Задан 07/08/2008 в 23:26
источник пользователем
На других языках...                            


13 ответов

голоса
50

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


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

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

>>> и "\ N {EURO ЗНАК}". Закодировать ( 'cp437')
Traceback (самый последний вызов последнего):
...
UnicodeEncodeError: «CharMap» кодек не может кодировать символ «\ u20ac» в позиции 0:
характер сопоставляется 

Я предполагаю, что это потому, что консоль 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 автоматически печатать ?вместо неудачи в этой ситуации?

Если этого достаточно , чтобы заменить все unencodable символы с ?в вашем случае , то вы можете установить PYTHONIOENCODINGenvvar :

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

В Python 3.6 +, кодировка задается PYTHONIOENCODINGenvvar игнорируется для интерактивных буферов консоли , если PYTHONLEGACYWINDOWSIOENCODINGenvvar не установлен непустой строки.

Ответил 24/08/2015 в 07:35
источник пользователем

голоса
29

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

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

Ответил 07/08/2008 в 23:32
источник пользователем

голоса
22

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

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

Ответил 09/01/2011 в 06:07
источник пользователем

голоса
11

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

Ответил 19/05/2012 в 19:48
источник пользователем

голоса
9

Ниже код будет делать вывод 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"
Ответил 06/01/2010 в 14:38
источник пользователем

голоса
3

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

chcp 65001 & set PYTHONIOENCODING=utf-8
Ответил 02/10/2018 в 22:11
источник пользователем

голоса
2

Для Python 2 раза:

print unicode(string, 'unicode-escape')

Для Python 3 раза:

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

Или попытаться выиграть-юникод-консоль:

pip install win-unicode-console
py -mrun your_script.py
Ответил 24/08/2017 в 18:00
источник пользователем

голоса
2

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

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

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

NB «пр» короче, чем набрать «печать» (и совсем немного короче, чем тип «safeprint») ...!

Ответил 09/03/2016 в 22:14
источник пользователем

голоса
1

TL; DR:

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

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

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

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

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

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

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

Ответил 01/07/2018 в 15:52
источник пользователем

голоса
1

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

Я не мог печатать utf8 символы в консоли окна. Печать 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 консоли.

Ответил 11/05/2017 в 20:08
источник пользователем

голоса
1

Вид, связанные с ответом по JF Себастьян, но более прямой.

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

>set PYTHONIOENCODING=UTF-8
Ответил 16/12/2015 в 07:53
источник пользователем

голоса
1

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

import sys
sys.getdefaultencoding()

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

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

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

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

Edit: подробнее можно найти в отличном нырял в книге Python

Ответил 11/08/2008 в 18:58
источник пользователем

голоса
0

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

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

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

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

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

Вместо того , чтобы бросать исключение, Python теперь отображает непечатные символы Unicode как \ XNn шестигранных коды, например:

  Halmalo п \ XE2 \ x80 \ x99 \ xc3 \ xa9tait плюс Цюй \ XE2 \ x80 \ x99un точка нуар

Вместо

  Halmalo n'était плюс точка qu'un нуар

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

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

Ответил 14/05/2016 в 17:47
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more