Что такое внутреннее представление строки в Python 3.x - PullRequest
23 голосов
/ 03 декабря 2009

В Python 3.x строка состоит из элементов порядкового номера Юникода. (См. Цитату из ссылки на язык ниже.) Каково внутреннее представление строки Unicode? Это UTF-16?

Элементы строкового объекта Unicode кодовые единицы. Код Unicode единица представлена ​​строковым объектом одного предмета и может содержать 16-битное или 32-битное значение, представляющее Порядковый номер Unicode (максимальное значение для порядковый номер дан в sys.maxunicode, и зависит от того, как Python настраивается во время компиляции). Суррогатные пары могут присутствовать в Unicode объект, и будет сообщено как два отдельных элемента.

Ответы [ 7 ]

26 голосов
/ 31 января 2012

Внутреннее представление изменится в Python 3.3, который реализует PEP 393 . Новое представление выберет одно или несколько из ascii, latin-1, utf-8, utf-16, utf-32, обычно пытающихся получить компактное представление.

Неявные преобразования в суррогатные пары будут выполняться только при общении с устаревшими API (они существуют только в окнах, где wchar_t - два байта); строка Python будет сохранена. Вот заметки о выпуске .

8 голосов
/ 28 февраля 2015

В Python 3.3 и выше внутреннее представление строки будет зависеть от строки и может быть любым из latin-1, UCS-2 или UCS-4, как описано в PEP 393 .

Для предыдущих Pythons внутреннее представление зависит от флагов сборки Python. Python может быть собран со значениями флагов --enable-unicode=ucs2 или --enable-unicode=ucs4. ucs2 сборки действительно используют UTF-16 в качестве внутреннего представления , а ucs4 сборки используют UCS-4 / UTF-32.

5 голосов
/ 03 декабря 2009

Глядя на исходный код для CPython 3.1.5, в Include/unicodeobject.h:

/* --- Unicode Type ------------------------------------------------------- */

typedef struct {
    PyObject_HEAD
    Py_ssize_t length;          /* Length of raw Unicode data in buffer */
    Py_UNICODE *str;            /* Raw Unicode buffer */
    long hash;                  /* Hash value; -1 if not set */
    int state;                  /* != 0 if interned. In this case the two
                                 * references from the dictionary to this object
                                 * are *not* counted in ob_refcnt. */
    PyObject *defenc;           /* (Default) Encoded version as Python
                                   string, or NULL; this is used for
                                   implementing the buffer protocol */
} PyUnicodeObject;

Символы хранятся в виде массива Py_UNICODE. Я полагаю, что на большинстве платформ Py_UNICODE равно #define d как wchar_t.

2 голосов
/ 03 декабря 2009

Во внутреннем представлении Unicode между Python 2.X и 3.X не было никаких изменений.

Это определенно НЕ UTF-16. UTF-что-либо - это байтовое ВНЕШНЕЕ представление.

Каждой единице кода (символ, суррогат и т. Д.) Был присвоен номер из диапазона (0, 2 ** 21).Это называется "порядковым".

Действительно, в документации, которую вы цитировали, все сказано.Большинство двоичных файлов Python используют 16-битные ординалы, которые ограничивают вас базовой многоязычной плоскостью («BMP»), если только вы не хотите копаться с суррогатами (удобно, если вы не можете найти свою рубашку для волос, и ваша лодыжка не работаетржавчина).Для работы с полным репертуаром Unicode вы бы предпочли «широкую сборку» (32 бита).

Вкратце, внутреннее представление в объекте Unicode представляет собой массив 16-разрядных целых чисел без знака или массив 32-разрядных целых чисел без знака (с использованием только 21 бита).

1 голос
/ 03 декабря 2009

Это зависит: см. здесь . Это все еще верно для Python 3 в отношении внутреннего представления.

0 голосов
/ 18 августа 2018
>>> import array; s = 'Привет мир!'; b = array.array('u', s).tobytes(); print(b); print(len(s) * 4 == len(b))
b'\x1f\x04\x00\x00@\x04\x00\x008\x04\x00\x002\x04\x00\x005\x04\x00\x00B\x04\x00\x00 \x00\x00\x00<\x04\x00\x008\x04\x00\x00@\x04\x00\x00!\x00\x00\x00'
True
>>> import array; s = 'test'; b = array.array('u', s).tobytes(); print(b); print(len(s) * 4 == len(b))
b't\x00\x00\x00e\x00\x00\x00s\x00\x00\x00t\x00\x00\x00'
True
>>> 
0 голосов
/ 03 декабря 2009

Я думаю, трудно судить о разнице между UTF-16, который является просто последовательностью 16-битных слов, и строковым объектом Python.

И если python скомпилирован с опцией Unicode = UCS4, он будет сравниваться между UTF-32 и строкой Python.

Итак, лучше учтите, что они относятся к разным категориям, хотя вы можете трансформировать друг друга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...