ТЛ; др
Ответ НИКОГДА ! (если вы действительно не знаете, что делаете)
9/10 раз решение может быть решено с правильным пониманием кодирования / декодирования.
1/10 человек имеют неправильно заданную локаль или среду и должны установить:
PYTHONIOENCODING="UTF-8"
в их среде для устранения проблем с консольной печатью.
Что это делает?
sys.setdefaultencoding("utf-8")
(вычеркнуто, чтобы избежать повторного использования) изменяет кодировку / декодирование по умолчанию, используемое всякий раз, когда Python 2.x необходимо преобразовать Unicode () в str () (и наоборот ) и кодировка не указана. То есть:
str(u"\u20AC")
unicode("€")
"{}".format(u"\u20AC")
В Python 2.x кодировка по умолчанию установлена на ASCII, и приведенные выше примеры завершатся с ошибкой:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)
(Моя консоль настроена как UTF-8, поэтому "€" = '\xe2\x82\xac'
, следовательно, исключение для \xe2
)
или
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)
sys.setdefaultencoding("utf-8")
позволит им работать на me , но не обязательно будет работать для людей, которые не используют UTF-8. По умолчанию ASCII гарантирует, что предположения о кодировке не будут включены в код
Консоль
sys.setdefaultencoding("utf-8")
также имеет побочный эффект, который появляется для исправления sys.stdout.encoding
, используемый при печати символов на консоли. Python использует языковой стандарт пользователя (Linux / OS X / Un * x) или кодовую страницу (Windows), чтобы установить это. Иногда язык пользователя нарушается, и для исправления консольной кодировки .
требуется всего лишь
PYTHONIOENCODING
.
Пример: * * тысяча пятьдесят-четырь
$ export LANG=en_GB.gibberish
$ python
>>> import sys
>>> sys.stdout.encoding
'ANSI_X3.4-1968'
>>> print u"\u20AC"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)
>>> exit()
$ PYTHONIOENCODING=UTF-8 python
>>> import sys
>>> sys.stdout.encoding
'UTF-8'
>>> print u"\u20AC"
€
Что плохого в sys.setdefaultencoding ("utf-8") ?
Люди разрабатывали Python 2.x в течение 16 лет, понимая, что кодировка по умолчанию - ASCII. UnicodeError
Методы обработки исключений были написаны для обработки преобразований строки в Unicode для строк, которые, как обнаружено, содержат не-ASCII.
С https://anonbadger.wordpress.com/2015/06/16/why-sys-setdefaultencoding-will-break-code/
def welcome_message(byte_string):
try:
return u"%s runs your business" % byte_string
except UnicodeError:
return u"%s runs your business" % unicode(byte_string,
encoding=detect_encoding(byte_string))
print(welcome_message(u"Angstrom (Å®)".encode("latin-1"))
Перед установкой кодировки по умолчанию этот код не сможет декодировать «Å» в кодировке ascii, а затем войдет в обработчик исключений, чтобы угадать кодировку и правильно превратить его в юникод. Печать: Angstrom (Å®) управляет вашим бизнесом. Как только вы установите код по умолчанию для utf-8, код обнаружит, что byte_string может интерпретироваться как utf-8, и поэтому он будет манипулировать данными и вернет это вместо этого: Angstrom (Ů) управляет вашим бизнесом.
Изменение того, что должно быть константой, окажет существенное влияние на модули, от которых вы зависите. Лучше просто исправить данные, входящие и исходящие из вашего кода.
Пример задачи
Хотя установка defaultencoding в UTF-8 не является основной причиной в следующем примере, она показывает, как проблемы маскируются и как, когда изменяется входная кодировка, код ломается неочевидным образом:
UnicodeDecodeError: кодек «utf8» не может декодировать байт 0x80 в позиции 3131: недопустимый начальный байт