Python2.7 печатает неправильные символы из Юникода с шестнадцатеричными символами

sys.getdefaultencoding()
-> utf8
test = u'tempête'
test
-> u'temp\xc3\xaate'
print(test)
-> tempête # WTF ?

sys.setdefaultencoding('ascii')
sys.getdefaultencoding()
-> ascii
test = u'tempête'
test
-> u'temp\xc3\xaate'
print(test)
-> tempête #...

Я наблюдаю эти результаты, когда делаю set_trace() из pdb.

В оболочке python2.7 у меня правильный результат:

sys.getdefaultencoding()
-> ascii
test = u'tempête'
test
-> u'temp\xc3\xaate'
print(test)
-> tempête # WTF ?

Я борюсь с этим часами...


person Pierre Criulanscy    schedule 24.02.2016    source источник
comment
Я не могу воссоздать проблему с python 2.7   -  person meltdown90    schedule 24.02.2016
comment
В оболочке python2.7 я получаю AttributeError: 'NoneType' object has no attribute 'CodecInfo'   -  person zondo    schedule 24.02.2016
comment
Пожалуйста, покажите нам вывод оболочки напрямую.   -  person thebjorn    schedule 24.02.2016
comment
Python 2.x никогда не должен иметь кодировку UTF-8 по умолчанию. Вам пришлось бы reload(sys) заставить эту работу работать, что должно сказать вам, что с ней нельзя играть.   -  person Alastair McCormack    schedule 25.02.2016
comment
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что ОП создал здесь более точное представление проблемы: stackoverflow.com/questions/35648216/   -  person Alastair McCormack    schedule 26.02.2016


Ответы (1)


Убедитесь, что ваша кодировка locale соответствует вашей эмуляции терминала. Введите locale для проверки.

sys.setdefaultencoding() не имеет ничего общего с печатью — Python использует вашу локаль для установки кодировки stdout, используемой при печати. См. sys.stdout.encoding.

Я могу частично воспроизвести вашу проблему следующим образом:

  1. Установить эмуляцию терминала на: UTF-8
  2. Установите локаль en_GB.ISO8859-1. т.е. Не UTF-8

    export LANG=en_GB.ISO8859-1
    
  3. Запустите свой код:

    >>> test = u'tempête'
    >>> test
    u'temp\xc3\xaate'
    

Тот факт, что ê становится Ã (U+00C3) и ª(U+00AA), является сутью проблемы, показывая, что Python считал, что кодировка должна быть 8-битным набором символов.

Я не могу воспроизвести ваш окончательный отпечаток, но подозреваю, что возился с setdefaultencoding() и все приготовил. См. мой ответ о том, почему это плохая идея: https://stackoverflow.com/a/34378962/1554386

person Alastair McCormack    schedule 24.02.2016
comment
Спасибо за ваш ответ и тот, на который вы ссылаетесь, очень интересно! Но у меня все еще есть проблема, не уверен, что это связано, наконец... Я очищаю веб-страницу с кодировкой iso-8859-1, scrapy возвращает ответ Unicode utf-8. Текст для удаления — «tempête», я поставил оператор pdb.set_trace(), чтобы проверить ответ, и он правильный: u'temp\xc3\xaate', но когда я попытался print, возникла та же проблема, что и выше: print(response) -> tempête. Я пытаюсь поместить этот ответ в файл json, и это также то, что печатается в файле json вместо «tempête». Любая подсказка по этому поводу? - person Pierre Criulanscy; 25.02.2016
comment
Хорошо, это типичная проблема XY. Было сделано слишком много предположений, когда проблема, вероятно, довольно проста в исходном коде. Вместо этого обновите вопрос, указав фактический код очистки. - person Alastair McCormack; 25.02.2016
comment
Может быть, мне следует создать совершенно новые вопросы, чтобы сообщения и ответы синхронизировались со старой темой? - person Pierre Criulanscy; 26.02.2016
comment
Хорошая идея. Создайте новый вопрос и вставьте сюда ссылку, чтобы я снова мог вам помочь. - person Alastair McCormack; 26.02.2016
comment
Здесь новый вопрос: stackoverflow.com/questions/35648216/ - person Pierre Criulanscy; 26.02.2016