is vs == для строк в Python

is vs == для строк в Python

@python_quiz

Разберем этот квиз

Короткое условие — есть два выражения, одно строит строку операцией повторения, другое — литерал. Нужно понять, что выведет следующий код:

python

Результат выполнения — строка с двумя булевыми значениями:

text

Далее объясню, почему так происходит, разберу похожие случаи и дам практические рекомендации.

Что сравнивают is и ==

  • Оператор == сравнивает значения (содержимое объектов). Для строк — сравнение по символам.
  • Оператор is проверяет тождество объектов, то есть указывает, ссылаются ли переменные на один и тот же объект в памяти.

Для проверки равенства строк используйте ==. is применим для проверки идентичности (например, if x is None:).

Почему в примере получается (False, True)

  • a = 'py' * 2 создаёт новую строку в момент выполнения (операция умножения/конкатенации выполняется во время выполнения кода), поэтому a указывает на отдельный объект.
  • b = 'pypy' — это литерал. В CPython компилятор может оптимизировать литералы (интернинг, объединение соседних литералов и т.п.), поэтому переменная с литералом может ссылаться на другой объект.
  • Содержимое строк одинаково, поэтому a == b даёт True.
  • Объекты разные, поэтому a is b даёт False (в стандартной реализации поведение интернинга для такой операции не гарантировано).

Показательные примеры

1) Литералы могут быть одним объектом:

python

2) Сборка строки во время выполнения — другой объект:

python

3) Соседние строковые литералы объединяются на этапе компиляции:

python

4) Принудительный intern через sys.intern:

python

Важные замечания и рекомендации

  • Поведение интернинга — деталь реализации (чаще встречается в CPython) и не входит в спецификацию языка. На разных реализациях Python (или даже в разных версиях CPython) поведение может отличаться.
  • Никогда не полагайтесь на is для сравнения содержимого строк — используйте ==.
  • is уместен для проверки на None (рекомендуется if x is None:) или для проверки тождественности объектов в тех ситуациях, где это нужно по семантике.
  • Если нужно гарантированно получить один и тот же объект для одинаковых строк (например, для экономии памяти или быстрых сравнений по ссылке), можно использовать sys.intern, но делайте это осознанно.

Вывод

Операция умножения/конкатенации строк обычно создаёт новый объект во время выполнения, поэтому идентичность (оператор is) не гарантируется, хотя содержимое может быть одинаковым (оператор ==). Для проверки равенства содержимого всегда используйте ==; is — только для проверки тождественности/специальных случаев (например, None).

Report Page