Проблема преобразования Python UTF-8 - PullRequest
6 голосов
/ 19 мая 2011

В моей базе данных я сохранил несколько символов UTF-8. Например. «α» в поле «имя»

Через Django ORM, когда я читаю это, я получаю что-то вроде

>>> p.name
u'\xce\xb1'
>>> print p.name
α

Я надеялся на «а».

После некоторого копания, думаю, если бы я сделал

>>> a = 'α'
>>> a
'\xce\xb1'

Итак, когда Python пытается отобразить '\ xce \ xb1', я получаю альфа, но когда он пытается отобразить u '\ xce \ xb1', это двойное кодирование?

Почему я получил u '\ xce \ xb1' во-первых? Есть ли способ, которым я могу просто вернуться '\ xce \ xb1'?

Спасибо. Моим знаниям UTF-8 и юникода действительно нужна помощь ...

Ответы [ 5 ]

2 голосов
/ 19 мая 2011

Кажется, что у вас есть отдельные байты строки в кодировке UTF-8, интерпретируемой как кодовые точки Юникода.Вы можете «декодировать» вашу строку из этой странной формы с помощью:

p.name = ''.join(chr(ord(x)) for x in p.name)

или, возможно,

p.name = ''.join(chr(ord(x)) for x in p.name).decode('utf8')

Один из способов «закодировать» ваши строки в эту форму -

''.join(unichr(ord(x)) for x in '\xce\xb1')

хотя у меня есть ощущение, что ваши строки фактически попали в это состояние из-за разногласий компонентов вашей системы по поводу используемой кодировки.

Возможно, вам придется исправить источник вашей плохой "кодировки""вместо того, чтобы просто исправить данные, которые в настоящее время находятся в вашей базе данных.И приведенный выше код может пригодиться для однократного преобразования неверных данных, но я бы посоветовал вам не вставлять этот код в приложение Django.

2 голосов
/ 19 мая 2011

Попробуйте поставить юникодную сигнатуру u перед вашей строкой, например, u'YOUR_ALFA_CHAR' и пересмотреть кодировку базы данных, потому что Django всегда поддерживает UTF-8.

1 голос
/ 19 мая 2011

Проблема в том, что p.name не был правильно сохранен и / или считан из базы данных.

Маленькая альфа-кодировка Unicode - это U + 03B1, а имя p.name должно быть напечатано как u '\ x03b1', или, если вы используете терминал с поддержкой Unicode, сам фактический символ альфа может быть напечатан в кавычках. Обратите внимание на разницу между u '\ xce \ xb1' и u '\ xceb1'. Первый представляет собой двухсимвольную строку, а второй - одну символьную строку. Я понятия не имею, как байт «03» UTF-8 был переведен в «CE».

0 голосов
/ 19 мая 2011

Вы можете превратить любую последовательность байтов во внутреннее представление Юникода с помощью функции декодирования:

print '\xce\xb1'.decode('utf-8')

Это позволяет импортировать последовательность байтов из любого источника и затем превратить ее в строку Unicode Python.

Ссылка: http://docs.python.org/library/stdtypes.html#string-methods

0 голосов
/ 19 мая 2011

Попробуйте преобразовать кодировку с p.name.encode('latin-1'). Вот демонстрация:

>>> print u'\xce\xb1'
α
>>> print u'\xce\xb1'.encode('latin-1')
α
>>> print '\xce\xb1'
α
>>> '\xce\xb1' == u'\xce\xb1'.encode('latin1')
True

Для получения дополнительной информации см. str.encode и Стандартные кодировки .

...