Есть код :
#!/usr/bin/python
# -*- coding: utf-8 -*-
hw = 'мир'
print hw
string = []
string.append(hw)
print string
После запуска выдает вот это:
мир
['\xd0\xbc\xd0\xb8\xd1\x80']
С кортежами тоже самое, как это исправить?
Есть код :
#!/usr/bin/python
# -*- coding: utf-8 -*-
hw = 'мир'
print hw
string = []
string.append(hw)
print string
После запуска выдает вот это:
мир
['\xd0\xbc\xd0\xb8\xd1\x80']
С кортежами тоже самое, как это исправить?
В общем случае на python2 - никак.
Вы пытаетесь получить строковое представление списка (в вашем случае это аналогично вызову repr). Однако это порождает проблемы так repr возвращает 'str' объект (на самом деле байтовую строку) которая содержит utf-8 символы этого списка, а когда вы пытаетесь это вывести python конвертирует в кодировку по умолчанию, которая для python 2 - это ascii, соответственно и выводится экранированный юникод.
Можно попробовать выводить так
print u'[%s]' % u','.join(unicode(x) for x in [u'привет', u'мир'])
В python 3 такой проблемы нет, потому что теперь всё юникод. И кодировка по умолчанию - utf-8. Везде. Поэтому всё работает как вы ожидаете
$python3
Python 3.5.1+ (default, Mar 30 2016, 22:46:26)
>>> print(['привет', 'мир'])
['привет', 'мир']
>>> repr(['привет', 'мир'])
"['привет', 'мир']"
>>> # аналогично
['привет', 'мир'].__str__()
"['привет', 'мир']"
unicode(x) здесь либо бесполезен (ввод в примере уже unicode тип имеет) либо вреден: если хотите байты в Юникод превратить, то следует использовать .decode() метод c указанием кодировки.
– jfs
Jun 25 '16 at 23:16
Используйте Unicode вместо байт для работы с текстом в Питоне. Например, добавьте from __future__ import unicode_literals, чтобы строковые константы создавали бы unicode объекты даже без явного u'' префикса. При чтении текста из файла используйте io.open(), чтобы получить unicode. При получении данных из сети, декодируйте байты в Юникод в соответствии с протоколом, например, если кодировка указана в Content-Type http заголовке:
text = data.decode(response.headers.getparam('charset'))
См. ответ, описывающий как получить текст, если данные возвращаются внешним процессом.
Напрямую печатайте списки/кортежи только для отладки, так как в этом случае для каждого элемента repr() функция вызывается: чья задача получить однозначное представление объекта, например, ['\xd0\xbc\xd0\xb8\xd1\x80'] это текстовое представление списка, содержащего байтовую строку. В Питоне 3, вы получили бы [b'\xd0\xbc\xd0\xb8\xd1\x80'] (явный b'' для байтовой константы). См. Чем отличается __repr__ от __str__?
Форматируйте списки/кортежи/другие коллекции явно:
>>> print ', '.join([u'мир'])
мир
В Питоне 2, repr() оставляет как есть только "printing characters" (в С локали это печатаемые ascii символы), для которых isprint() возвращает ненулевое значение (такие символы являются текстовым представлением самих себя). Остальные символы экранируются:
>>> print([u'мир'])
[u'\u043c\u0438\u0440']
На Питоне 3, str(some_list) также вызывает repr() для элементов списка some_list, но при этом печатаемые в текущем окружении символы могут быть отображены как есть (мир) вместо использования экранирования ('\u043c\u0438\u0440').
Схожие вопросы:
u'мир'. То что вам показывает внутри списка - это ваш текст в кодировке utf-8. – insolor Jun 25 '16 at 14:16print string[0], а на выводprintот списка не обращать внимание, т.к. к элементам списка применяетсяrepr, который делает строки с кириллицей нечитаемыми. Правда, под Windows и такой вывод остается не читаем, т.к. кодировка консоли - cp866 а не utf-8. Зато работает нормально с юникодными строками. – insolor Jun 25 '16 at 14:53reprпортит вывод, а внутри оно все нормально хранится. – insolor Jun 25 '16 at 18:17