UnicodeEncodeError: кодек 'charmap' не может кодировать - символ сопоставляется с <undefined>, функция печати [duplicate]

На этот вопрос уже есть ответ:

Python, Unicode и консоль Windows 13 ответов

Я пишу программу на Python (Python 3.3) для отправки некоторых данных на веб-страницу методом POST. В основном для процесса отладки я получаю результат страницы и отображаю его на экране, используяprint() функция.

Код такой:

conn.request("POST", resource, params, headers)
response = conn.getresponse()
print(response.status, response.reason)
data = response.read()
print(data.decode('utf-8'));

theHTTPResponse .read() метод возвращаетbytesлемент @, кодирующий страницу (это хорошо отформатированный документ UTF-8) Казалось, все нормально, пока я не перестал использовать IDLE GUI для Windows и вместо этого использовал консоль Windows. Возвращаемая страница имеет символ U + 2014 (em-dash), который функция печати хорошо транслирует в графическом интерфейсе Windows (я полагаю, кодовая страница 1252), но не в консоли Windows (кодовая страница 850). Учитываяstrict поведение по умолчанию я получаю следующую ошибку:

UnicodeEncodeError: 'charmap' codec can't encode character '\u2014' in position 10248: character maps to <undefined>

Я мог бы исправить это, используя этот довольно уродливый код:

print(data.decode('utf-8').encode('cp850','replace').decode('cp850'))

Теперь замените оскорбительный символ "-" на?. Не идеальный случай (дефис должен быть лучшей заменой), но достаточно хороший для моей цели.

Есть несколько вещей, которые мне не нравятся в моем решении.

Код ужасен со всем этим декодированием, кодированием и декодированием. Это решает проблему только для этого случая. Если я портирую программу для системы, использующей какую-то другую кодировку (latin-1, cp437, обратно в cp1252 и т. Д.), Она должна распознавать целевую кодировку. Это не. (например, при повторном использовании графического интерфейса IDLE также теряется emdash, чего раньше не было) Было бы лучше, если бы перевод слова «перевод» в дефис вместо взрыва допроса.

Проблема не в emdash (я могу придумать несколько способов решения этой конкретной проблемы), но мне нужно написать надежный код. Я кормлю страницу данными из базы данных, и эти данные могут вернуться. Я могу предвидеть множество других противоречивых случаев: 'Á' U + 00c1 (что возможно в моей базе данных) может переводиться в CP-850 (кодировка консоли DOS / Windows для западноевропейских языков), но не в CP-437 (кодировка для США). Английский, который используется по умолчанию во многих установках Windows).

Итак, вопрос:

Есть ли лучшее решение, которое делает мой код независимым от кодировки выходного интерфейса?

Ответы на вопрос(6)

Ваш ответ на вопрос