В чём разница между == и is в Python?

«В чём разница между == и is в Python?» — вопрос из категории Python, который задают на 28% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Python == и is — это операторы сравнения с принципиально разной семантикой, и их путаница — частая причина ошибок в тестах.

  • == (оператор равенства): Сравнивает значения объектов. Он вызывает магический метод __eq__() у объекта. Если __eq__ не определён, сравниваются идентификаторы объектов (как is).
  • is (оператор идентичности): Сравнивает идентификаторы объектов в памяти (фактически, адреса). Проверяет, ссылаются ли две переменные на один и тот же объект.

Практический пример для тестирования:

list_a = [1, 2, 3]
list_b = [1, 2, 3]  # Другой объект с теми же значениями
list_c = list_a     # Ссылка на тот же объект, что и list_a

print(list_a == list_b)  # True: значения одинаковые
print(list_a is list_b)  # False: это разные объекты в памяти

print(list_a == list_c)  # True: значения одинаковые
print(list_a is list_c)  # True: это один и тот же объект

Когда что использовать в автотестах:

  • assert a == b: Используется в 99% случаев для проверки ожидаемого значения результата, содержимого списка, текста элемента и т.д.
  • assert a is b или assert a is None: Используется для проверки на None, True, False (синглтоны в Python) или когда нужно гарантировать, что это именно тот же объект (например, проверка, что функция вернула тот же инстанс, а не создала новый).

Важное исключение (источник ошибок):

# Из-за кэширования маленьких целых чисел в CPython:
a = 256
b = 256
print(a is b)  # True (но это деталь реализации!)

x = 1000
y = 1000
print(x is y)  # False (может быть False в зависимости от контекста)

Вывод для QA: Всегда используйте == для сравнения значений. Используйте is только для сравнения с None, True, False или в очень специфичных случаях, когда важна идентичность объекта, а не его значение.