Вопрос с собеседования · Python

Почему a is b для чисел и строк иногда True, а иногда False?

MiddleВнутреннее устройство
Ещё спрашивают так:
  • Что такое кэш малых целых и интернирование строк в Python?
Коротко

CPython заранее создаёт целые от −5 до 256 и переиспользует их — is для них True. Строки, похожие на идентификаторы, и константы в одном блоке кода интернируются компилятором. Всё это детали реализации: значения сравнивают через ==, а is — только с None и синглтонами.

  • a = 257; b = 257 в интерактивной оболочке — разные объекты, в одном файле — может быть один (свёртка констант)
  • sys.intern(s) — интернировать строку явно (ускоряет сравнение ключей)
  • Python 3.8+ предупреждает: SyntaxWarning "is" with a literal

А ещё Аналог в Java — кэш Integer от −128 до 127

Подробно

Кэш малых целых. При старте CPython создаёт объекты для чисел от −5 до 256. Любое вычисление с таким результатом возвращает готовый объект, поэтому a = 100; b = 100; a is b — True.

Почему 257 ведёт себя по-разному. В интерактивной оболочке каждая строка компилируется отдельно — два разных объекта, is даёт False. В файле обе константы попадают в один блок кода, компилятор объединяет одинаковые константы — is может дать True. Результат зависит от способа запуска и версии.

Интернирование строк. Строковые литералы, похожие на идентификаторы (буквы, цифры, подчёркивание), интернируются автоматически: имена атрибутов и ключи словарей сравниваются по адресу быстрее. sys.intern() делает это явно — полезно, когда миллионы одинаковых строк (теги, коды) занимают память.

Правило: is проверяет идентичность объекта и уместен только для None, True/False, Ellipsis и собственных маркеров-синглтонов. Значения сравнивают через ==.

Что хотят услышать

  • Кэш малых целых и интернирование строк.
  • Почему результат зависит от контекста.
  • Правило: is только для None и синглтонов.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗Строки всегда интернируются, поэтому для них is надёжен, а для чисел — только в диапазоне до 256
  • ✗is всегда True для равных чисел
  • ✗Интернирование — гарантия языка, на него можно полагаться
  • ✓CPython кэширует целые от −5 до 256 и часть строк — деталь реализации; сравнивают через ==

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования