is vs == и кеширование целых в CPython
@python_quizРазберем этот квиз
Код, который требуется проанализировать:

Коротко: вывод этого кода — True False True. Ниже объясню почему, разберу смысл операторов и покажу варианты с демонстрацией.
Что делают is и ==
- is — проверяет тождественность объектов: указывают ли две переменные на один и тот же объект в памяти.
- == — проверяет равенство значений (вызывает метод сравнения объектов).
Обычно для сравнения значений чисел и строк нужно использовать ==. is используют для проверки идентичности объектов (например, None, синглтоны).
Кеширование целых в CPython
Реализация CPython хранит в кэше маленькие целые числа в диапазоне примерно от -5 до 256. Это значит, что для этих значений создаётся один объект, и ссылки на него переиспользуются. По этой причине любые две переменные, содержащие одно и то же маленькое целое, будут указывать на один объект — и выражение с is вернёт True.
Диапазон кеша — поведение CPython, это реализация, а не универсальное свойство языка Python.
Разбор примера
a = b= 256 — обе переменные получают ссылку на один объект с числом 256. Поэтому a is b → True.c = 257— объект с 257 обычно не кэшируется, поэтому c указывает на отдельный объект с этим значением.- c is 257 — поскольку литерал 257 в данном контексте чаще создаёт отдельный объект, сравнение тождественности обычно даёт False.
- c == 257 — сравнение значений, очевидно, True.
Итоговый вывод:

Анализ всех вариантов (логика)
Предложенные ответы представляли возможные комбинации трёх логических выражений: (a is b), (c is 257), (c == 257). Объяснение для каждой позиции:
- Первая позиция (a is b): для 256 это True из-за кеша.
- Вторая позиция (c is 257): для 257 обычно False (отдельный объект).
- Третья позиция (c == 257): всегда True, так как значения совпадают.
Поэтому комбинация True False True — соответствует поведению CPython в типичном случае.
Демонстрация и нюансы
Иногда компилятор может оптимизировать литералы в одном кодовом объекте, и поведение с is для больших чисел может выглядеть по-разному в отдельных окружениях. Чтобы надёжно продемонстрировать, что объекты с числом 257 различны, можно создавать их в рантайме (например, через int()):

Еще демонстрация id() для визуального подтверждения:

Замечание: в интерактивной сессии или при оптимизациях компилятора поведение с повторяющимися литералами может отличаться, поэтому опираться на is для чисел нельзя.
Выводы и рекомендации
- is — для проверки идентичности объектов (например, проверка на None: x is None).
- == — для сравнения значений, использовать его для чисел и строк.
- CPython кеширует целые в диапазоне примерно [-5, 256], поэтому сравнения на is для этих значений могут быть True.
- Не полагайтесь на is для определения равенства чисел — это ошибка стиля и потенциальный источник багов.