Латинские символы Python и Unicode

У меня есть древовидная структура, в которой ключевые слова могут содержать латинские символы. У меня есть функция, которая перебирает все листья дерева и добавляет каждое ключевое слово в список при определенных условиях.

Вот код, который у меня есть для добавления этих ключевых слов в список:

print "Adding: " + self.keyword
leaf_list.append(self.keyword)
print leaf_list

Если ключевое слово в этом случае université, то мой вывод:

Adding: université
['universit\xc3\xa9']

Похоже, что функция печати правильно отображает латинский символ, но когда я добавляю его в список, он декодируется.

Как я могу это изменить? Мне нужно иметь возможность распечатать список со стандартными латинскими символами, а не с их декодированной версией.


person lightningmanic    schedule 22.04.2014    source источник
comment
Ваш терминал умеет интерпретировать кодировку UTF-8. Содержимое строки - это просто (декодированные) байты.   -  person Martijn Pieters    schedule 22.04.2014


Ответы (2)


У вас нет объектов unicode, а есть байтовые строки с текстом в кодировке UTF-8. Печать таких строк байтов на вашем терминале может работать, если ваш терминал настроен на обработку текста UTF-8.

При преобразовании списка в строку содержимое списка отображается в виде представлений; результат функции repr(). Представление строкового объекта использует escape-коды для любых байтов за пределами печатаемого диапазона ASCII; новые строки заменяются, например, на \n. Ваши байты UTF-8 представлены escape-последовательностями \xhh.

Если бы вы использовали объекты Unicode, в представлении использовались бы \xhh escape-последовательности по-прежнему, но только для кодовых точек Unicode в диапазоне Latin-1 (за пределами ASCII) (остальные показаны с \uhhhh и \Uhhhhhhhh escape-последовательности в зависимости от их кодовая точка); при печати Python автоматически кодирует такие значения в правильную кодировку для вашего терминала:

>>> u'université'
u'universit\xe9'
>>> len(u'université')
10
>>> print u'université'
université

Сравните это со строками байтов:

>>> 'université'
'universit\xc3\xa9'
>>> len('université')
11
>>> 'université'.decode('utf8')
u'universit\xe9'
>>> print 'université'
université

Обратите внимание, что длина отражает то, что кодовая точка é также закодирована в два байта. Это был мой терминал, который представил Python с байтами \xc3\xa9 при вставке символа é в сеанс Python, кстати, поскольку он настроен на использование UTF-8, и Python обнаружил это и декодировал байты, когда я определил u'..' Unicode объектный литерал.

Я настоятельно рекомендую вам прочитать следующие статьи, чтобы понять, как Python обрабатывает Unicode и в чем разница между текстом Unicode и закодированными байтовыми строками:

person Martijn Pieters    schedule 22.04.2014

Когда вы печатаете список, вы получаете repr содержащихся в нем элементов, которые для строк отличаются от их содержимого:

>>> a = ['foo', 'bär']
>>> print(a[0])
foo
>>> print(repr(a[0]))
'foo'
>>> print(a[1])
bär
>>> print(repr(a[1]))
'b\xc3\xa4r'

Вывод repr должен быть удобным для программиста, а не для пользователя, отсюда и кавычки и шестнадцатеричные коды. Чтобы вывести список в удобном для пользователя виде, напишите собственный цикл. Например.

>>> print '[', ', '.join(a), ']'
[ foo, bär ]
person Fred Foo    schedule 22.04.2014