ПрограммированиеBackend/Python разработчик

Объясните семантику оператора is и оператора == в Python. В чем разница между ними и когда использование каждого критично? Приведите примеры типичных ловушек.

Проходите собеседования с ИИ помощником Hintsage

Ответ

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

is следует использовать для сравнения именно идентичности (например, с None или для singleton-объектов), а не для проверки равенства значений.

Пример:

a = [1, 2, 3] b = [1, 2, 3] print(a == b) # True print(a is b) # False c = None d = None print(c is d) # True

При работе с небольшими целыми числами или строками интерпретатор может использовать "интернирование" (cached objects), что иногда делает is истинным для равных значений, но это не должно использоваться в логике программы.


Вопрос с подвохом

Вопрос: Что выведет следующий код?

a = 256 b = 256 print(a is b) c = 257 d = 257 print(c is d)

Почему?

Ответ: Для значений от -5 до 256 Python использует пул целых чисел. Значения в этом диапазоне всегда указывают на одни и те же объекты, поэтому a is b даст True. 257 — уже вне пула, поэтому c is d будет False (объекты независимы).


История

Пример 1

В одном микросервисе проверку равенства строк провели с помощью is вместо ==. Из-за оптимизаций интерпретатора программа работала "стабильно" в тестах, но начала сбоить после перекомпиляции или других изменений среды.


Пример 2

Один разработчик для сравнения чисел использовал оператор is вместо ==. Это сработало для маленьких чисел (благодаря пулу), но для больших — дало сбои и непредсказуемые результаты, что вызвало некорректную работу расчётов.


Пример 3

В проектирование системы авторизации проверяли пришедший JSON с помощью is None (корректно), а затем по аналогии сделали так же для строк: if status is "ok". Это оказалось ошибкой — иногда условие не выполнялось, приводя к неверной логике обработки данных.