Python: почему ("hello" - это "hello") оценивается как True? [дубликат]

этот вопрос уже есть ответ здесь:

почему "hello" is "hello" производства True в Python?

Я прочитал следующее здесь:

Если две строковые литералы равны, их же память местоположение. Строка является неизменяемой сущностью. Никакого вреда не будет. быть сделано.

Итак, есть одно и только одно место в памяти для каждой строки Python? Звучит довольно странно. Что здесь происходит?

7 ответов


Python (например, Java, C, C++, .NET) использует пул строк / интернирование. Интерпретатор понимает, что "hello" - это то же самое, что и" hello", поэтому он оптимизирует и использует то же место в памяти.

еще один момент: "hell" + "o" is "hello" ==>True


Итак, есть одно и только одно место в памяти для каждой строки Python?

нет, только те, которые интерпретатор решил оптимизировать, что является решением, основанным на политике, которая не является частью спецификации языка и которая может меняться в разных версиях CPython.

например. на моей установке (2.6.2 Linux):

>>> 'X'*10 is 'X'*10
True
>>> 'X'*30 is 'X'*30
False

аналогично для ints:

>>> 2**8 is 2**8
True
>>> 2**9 is 2**9
False

поэтому не полагайтесь на "string" - это "string": даже просто глядя на C реализация это небезопасно.


литеральные строки, вероятно, сгруппированы на основе их хэша или чего-то подобного. Две одинаковые литеральные строки будут храниться в одной и той же памяти, и любые ссылки ссылаются на это.

 Memory        Code
-------
|          myLine = "hello"
|        /
|hello  <
|        \
|          myLine = "hello"
-------

на is оператор возвращает true, если оба аргумента являются одним и тем же объектом. Ваш результат является следствием этого, и цитирует чуть.

в случае строковых литералов они интернированы, что означает, что они сравниваются с известными строками. Если идентичная строка уже известна, литерал принимает это значение вместо альтернативного. Таким образом, они становятся одним и тем же объектом, и выражение истинно.


интерпретатор/компилятор Python анализирует строковые литералы, т. е. цитируемый список символов. Когда он это делает, он может обнаружить "я видел эту строку раньше" и использовать то же представление, что и в прошлый раз. Он может сделать это, так как знает, что строки, определенные таким образом, не могут быть изменены.


Почему это странно. Если строка неизменяема, имеет смысл хранить ее только один раз. .NET имеет такое же поведение.


Я думаю, что если любые две переменные (а не только строки) содержат одно и то же значение, значение будет сохранено только один раз, а не дважды, и обе переменные будут указывать на одно и то же место. Это экономит память.