Как Python делает магию строк?
Сегодня меня смутило сравнение строк: кажется, что python повторно использует строки (что разумно сделать, поскольку они неизменны). Чтобы проверить этот факт, я сделал следующее:
>>> a = 'xxx'
>>> b = 'xxx'
>>> a == b
True
>>> a is b
True
>>> id(a)
140141339783816
>>> id(b)
140141339783816
>>> c = 'x' * 3
>>> id(c)
140141339783816
>>> d = ''.join(['x', 'x', 'x'])
>>> id(d)
140141339704576
Что немного удивительно. некоторые вопросы:
- Проверяет ли python все содержимое своей таблицы строк при определении новых строк?
- Есть ли ограничение на размер строки?
- Как работает этот механизм (сравнивая хэши строк?)
- Похоже, он не используется для всех видов генерируемых строк. Какое правило здесь?
1 ответ
Поскольку у этого вопроса есть некоторые положительные отзывы (хотя это несколько дублирует), я отвечу здесь на мои оригинальные вопросы (благодаря комментариям выше):
- Да, python проверяет все содержимое внутренней таблицы: но только для некоторых строк, в основном тех, которые также могут использоваться в качестве идентификаторов. Идея состоит в том, что прием ускорения, используемый для обработки идентификатора интерпретатором Python (компилятором?), Также полезен для обработки общих строк. Процесс называется интернированием
- Насколько я знаю, нет ограничения на размер строки, но есть другие правила для повторного использования строк (в основном: они должны выглядеть как идентификаторы Python)
- Да, таблица - это обычный python dict, а строки имеют хэш для поиска.
- Он используется только для строковых литералов и константных выражений. В основном для всего, что интерпретатор Python может вывести на этапе компиляции.
Чтобы прояснить последний пункт, следующие фрагменты оценивают во всех случаях строку 'xxx'
, но они относятся по-разному в отношении интернирования.
Это константное выражение:
'x' * 3
Но это не так
a = 'x'
a * 3 # this is no constant expression, so no interning can be applied.
И это не выражение
''.join(['x', 'x', 'x']) # this is no expression (a function is called)