В чём разница между операторами ‘==’ и ‘is’ в Python?

Ответ

В Python операторы == и is выполняют принципиально разные проверки:

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

Наглядный пример:

list_a = [1, 2, 3]
list_b = list_a          # list_b ссылается на ТОТ ЖЕ объект
list_c = [1, 2, 3]       # list_c ссылается на НОВЫЙ объект с такими же значениями

print(list_a == list_b)  # True: значения одинаковые [1,2,3] == [1,2,3]
print(list_a is list_b)  # True: это один и тот же объект в памяти

print(list_a == list_c)  # True: значения одинаковые [1,2,3] == [1,2,3]
print(list_a is list_c)  # False: это разные объекты в памяти (id(list_a) != id(list_c))

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

  • Используйте == для сравнения содержимого (чисел, строк, списков, значений атрибутов объектов).
  • Используйте is для проверки на None, True, False (синглтоны) или чтобы убедиться, что две переменные указывают на один объект.
# Правильно для синглтонов
if result is None:
    print("Результат отсутствует")
if success is True:
    print("Операция успешна")

# НЕПРАВИЛЬНО (хотя может работать)
if result == None:  # Стилистически хуже, может быть переопределён __eq__
    pass

Важное замечание о кэшировании (interning): Python может кэшировать небольшие целые числа и короткие строки для оптимизации. Это может ввести в заблуждение:

a = 256
b = 256
print(a is b)  # True (для чисел от -5 до 256 это гарантировано в CPython)

x = 1000
y = 1000
print(x is y)  # Может быть True или False в зависимости от реализации/контекста
# ВСЕГДА используйте == для сравнения значений чисел и строк!

Ответ 18+ 🔞

Да ты посмотри, какая, блядь, тонкая материя! Два оператора, вроде как одно и то же делают, а нихуя подобного, ёпта!

Вот смотри, как в жизни: == — это как сравнивать две бутылки водки. Обе «Столичная», обе по пол-литра, обе из одного магазина. По значению — одинаковые, да? Можно сказать водка1 == водка2True, и выпить можно любую, разницы-то нет.

А вот is — это уже про то, одна ли это бутылка на двоих. Ты взял бутылку, я за неё же ухватился. Мы оба держимся за один и тот же объект, блядь! водка1 is водка2True, только вот драка сейчас начнётся, потому что она одна, сука!

Вот тебе наглядный пиздец, прости, пример:

list_a = [1, 2, 3]
list_b = list_a          # list_b — это просто второе имя для list_a. Одна бутылка, два горлышка.
list_c = [1, 2, 3]       # list_c — это новая, отдельная бутылка, хоть и налито то же самое.

print(list_a == list_b)  # True — ну да, внутри [1,2,3] и [1,2,3]
print(list_a is list_b)  # True — это ж одна и та же штука в памяти, один список!

print(list_a == list_c)  # True — значения-то одинаковые, оба списка с цифрами
print(list_a is list_c)  # False — а вот это уже разные объекты! Две разные бутылки.

Так когда чем пользоваться, чтобы не облажаться?

  • == — это твой рабочий инструмент. Хочешь узнать, одинаковые ли числа, строки, списки? Сравнивай значения. «А этот текст такой же, как тот?» — text1 == text2.
  • is — это спецоперация, блядь. Используй его в трёх случаях:
    1. Проверить, None ли что-то (if result is None).
    2. Проверить, точно ли True или False (if success is True). Хотя для булевых часто и == сойдёт.
    3. Убедиться, что две переменные — это один и тот же объект, а не копия. Редко, но бывает нужно.
# Вот так — правильно и идиоматично
if error is None:
    print("Всё чисто, можно дальше ебашить")
if done is False:
    print("Работа ещё не сделана, сиди, мудак, работай")

# А вот так — некрасиво и может подвести (мало ли кто __eq__ переопределил)
if error == None:  # Фу, блядь, так не пиши
    pass

А теперь главный подвох, ебать мои старые костыли!

Пайтон — он хитрая жопа. Он иногда для оптимизации делает так, что маленькие целые числа или короткие строки становятся одним объектом. Это называется интернирование.

a = 256
b = 256
print(a is b)  # True — потому что 256 в CPython закешировано, это один объект.

x = 1000
y = 1000
print(x is y)  # А вот тут уже мутно! Может быть True в твоей консоли, а False в скрипте. Полная хуйня!

Запомни раз и нахуй: для сравнения чисел и строк ВСЕГДА используй ==. is — это не про значения, это про идентичность в памяти. Не наёбывайся на этом, а то будет тебе False там, где ты True ждал, и волнение ебать накроет с головой.

Короче, == — «похожи как?», is — «одно и то же?». Вот и вся философия, блядь.