Unicode против UTF-8 путаница в Python / Django?

Я наткнулся на этот отрывок из учебника по Джанго :

Модели Django имеют метод str () по умолчанию, который вызывает unicode () и преобразует результат в строку байтов UTF-8. Это означает, что unicode (p) вернет строку Unicode, а str (p) вернет нормальную строку с символами, закодированными как UTF-8.

Теперь я запутался, потому что afaik Unicode не является каким-то конкретным представлением, так что же такое «строка Unicode» в Python? Означает ли это UCS-2? Googling обнаружил этот "Python Unicode Tutorial", в котором смело говорится

Unicode - это двухбайтовая кодировка, которая охватывает все распространенные в мире системы записи.

что не так или нет? Меня много раз смущали проблемы с набором символов и кодировкой, но здесь я совершенно уверен, что читаемая документация запутана. Кто-нибудь знает, что происходит в Python, когда он дает мне «строку Unicode»?

22.08.2008 12:01:53
5 ОТВЕТОВ
РЕШЕНИЕ

Что такое "строка Unicode" в Python? Означает ли это UCS-2?

Строки Unicode в Python хранятся как UCS-2 (16-битное представление фиксированной длины, почти такое же, как UTF-16), так и UCS-4 / UTF-32 (32-битное представление фиксированной длины). Это опция времени компиляции; в Windows это всегда UTF-16, в то время как многие дистрибутивы Linux устанавливают UTF-32 («широкий режим») для своих версий Python.

Как правило, вас это не должно волновать: вы будете видеть кодовые точки Unicode как отдельные элементы в своих строках и не будете знать, хранятся ли они как два или четыре байта. Если вы находитесь в сборке UTF-16 и вам нужно обрабатывать символы вне базовой многоязычной плоскости, вы будете делать это неправильно, но это все еще очень редко, и пользователи, которым действительно нужны дополнительные символы, должны компилировать широкие сборки.

прямо не так, или это?

Да, это совершенно неправильно. Честно говоря, я думаю, что учебник довольно старый; он, вероятно, предшествует широким строкам Unicode, если не Unicode 3.1 (версия, которая вводит символы вне базовой многоязычной плоскости).

Существует еще один источник путаницы, вытекающий из привычки Windows использовать термин «Unicode» для обозначения, в частности, кодировки UTF-16LE, которую NT использует для внутреннего использования. Люди из Microsoftland могут часто копировать эту несколько вводящую в заблуждение привычку.

48
21.10.2009 10:11:53
Я думаю, что разница между UCS-2 и UTF-16, по крайней мере, заслуживает внимания, поскольку одна имеет фиксированную длину, а другая - нет. Если я вообще забочусь о внутреннем представительстве, я хочу это знать.
Hanno Fietz 21.10.2009 10:00:38
Это действительно UCS-2? Так как Python может обрабатывать символы> sys.maxunicode, то только в том случае, если у вас есть символы в середине. С UCS-2, как было бы возможно отобразить / сохранить / кодировать / декодировать символы выше sys.maxunicode? (Протестировано с Python 3.1)
u0b34a0f6ae 10.12.2009 16:00:35
Это должен быть UTF-16, поскольку UCS-2 не поддерживает суррогатные пары. Demontration на узкой сборки Python 3.1, преодолев персонажа вверх в суррогаты: list(chr(sys.maxunicode + 1)). Результат есть ['\ud800', '\udc00']. Может ли кто-нибудь подтвердить это на (узком) Python 2?
u0b34a0f6ae 10.12.2009 16:08:03
Да, Python2 также позволяет создавать один не-BMP символ в виде двух суррогатных единиц кода через unichrили \U00nnnnnnстроковый литерал escape. Технически, он использует UTF-16 с семантикой UCS-2. Я ненавижу использовать термин «UTF-16», так как он может означать либо последовательность 16-битных кодовых блоков, либо кодирование байтов с большим или меньшим порядком байтов того же самого, что вызывает полную загрузку путаницы. На практике все «UCS-2» - это действительно «UTF-16», поскольку последний является наиболее часто используемым надмножеством первого.
bobince 10.12.2009 16:46:08
Длина строки Unicode Python в узкой сборке Unicode - это количество единиц кода UTF-16 , а не фактических точек кода Unicode. Усечение и другие параметры среза, которые идут по произвольному индексу, действительно могут разделить суррогатную пару пополам, что приведет к некоторым пропущенным / замененным символам. На узкой сборке unichr(0x10345)просто терпит неудачу; len(u'\U00010345')есть 2. Это цена, которую вы платите за простое взаимодействие с Win32 UTF-16LE API. Большинство других сред используют UCS-4, который не страдает от такой проблемы.
bobince 2.11.2010 20:15:21

Python хранит Unicode как UTF-16. str () вернет UTF-8 представление строки UTF-16.

0
22.08.2008 12:03:47
Python хранит строки Unicode как UTF-16 или UTF-32, в зависимости от платформы и параметров компиляции.
tzot 7.02.2009 19:18:52
На какой платформе str (unicode_string) возвращает UTF-8? Вы пробовали это? например, str (u "\ u0369")
tzot 7.02.2009 19:20:17
Неправильно по обоим пунктам. str(unicode_val)будет кодировать в соответствии с sys.getdefaultencoding().
Tobu 31.01.2012 13:16:09

Из Википедии на UTF-8 :

UTF-8 (8-битный формат преобразования UCS / Unicode) - это кодировка символов переменной длины для Unicode. Он может представлять любой символ в стандарте Unicode , однако первоначальное кодирование байтовых кодов и назначений символов для UTF-8 обратно совместимо с ASCII. По этим причинам он постоянно становится предпочтительной кодировкой для электронной почты, веб-страниц [1] и других мест, где символы хранятся или передаются в потоковом режиме.

Таким образом, это может быть от одного до четырех байтов в зависимости от того, какой символ вы хотите представить в области Unicode.

Из Википедии в Юникоде:

В области вычислительной техники Unicode является отраслевым стандартом, позволяющим компьютерам последовательно представлять и манипулировать текстом, выражаемым в большинстве мировых систем письма .

Таким образом, он может представлять большинство (но не все) мировых систем письма.

Надеюсь, это поможет :)

-1
22.08.2008 12:10:14

так что такое "строка Юникода" в Python?

Python «знает», что ваша строка Unicode. Следовательно, если вы сделаете регулярное выражение, он будет знать, какой персонаж, а какой нет и т.д., что действительно полезно. Если вы сделали strlen, это также даст правильный результат. Например, если вы подсчитали число строк в Hello, вы получите 5 (даже если это Unicode). Но если вы подсчитали количество иностранных слов, и эта строка не была строкой Юникода, вы получите намного больший результат. Pythong использует информацию из базы данных символов Unicode для идентификации каждого символа в строке Unicode. Надеюсь, это поможет.

-2
25.08.2008 14:01:34

Тем временем я провел изысканное исследование, чтобы проверить, что такое внутреннее представление в Python, а также каковы его пределы. « Правда о Unicode в Python » - очень хорошая статья, которая цитируется непосредственно разработчиками Python. По-видимому, внутренним представлением является UCS-2 или UCS-4 в зависимости от переключателя времени компиляции. Итак, Джон, это не UTF-16, но твой ответ в любом случае поставил меня на правильный путь, спасибо.

8
9.02.2009 13:50:39