В чем разница между is и ==?
🔹 == vs is в Python: в чём разница?
В Python есть два оператора сравнения, которые могут показаться похожими, но на самом деле они сравнивают разные вещи:
Оператор | Что сравнивает? | Возвращает |
---|---|---|
\== | Значения объектов (содержимое) | True/False |
--- | --- | --- |
is | Идентичность объектов (один ли объект в памяти) | True/False |
--- | --- | --- |
🔸 ==: сравнение значений
Оператор == проверяет, одинаково ли содержимое двух объектов, даже если они находятся в разных местах памяти.
🔹 Пример:
a = \[1, 2, 3\]
b = \[1, 2, 3\]
print(a == b) # ✅ True — содержимое списков одинаковое
Списки a и b имеют одинаковое значение, но это разные объекты в памяти.
🔸 is: сравнение идентичности объектов
Оператор is проверяет, указывают ли обе переменные на один и тот же объект в памяти.
🔹 Пример:
a = \[1, 2, 3\]
b = \[1, 2, 3\]
print(a is b) # ❌ False — это два разных объекта
Несмотря на одинаковое содержимое, a и b — разные ссылки (адреса в памяти).
🔸 Подтверждение через id()
Функция id() возвращает уникальный идентификатор объекта (его адрес в памяти):
print(id(a)) # например, 139922224955264
print(id(b)) # другой адрес
print(a is b) # False
🔹 Когда is возвращает True?
Когда две переменные ссылаются на один и тот же объект:
a = \[1, 2, 3\]
b = a
print(a is b) # ✅ True — это один и тот же объект
🔸 Примеры с неизменяемыми типами
Python интернирует (кэширует) некоторые объекты: например, маленькие числа и строки.
Пример с числами:
a = 10
b = 10
print(a is b) # ✅ True (интернирование)
x = 5000
y = 5000
print(x is y) # ❌ Может быть False (вне интервала кэширования)
Пример со строками:
a = "hello"
b = "hello"
print(a is b) # ✅ Часто True — строки кэшируются
a = "hello world, this is long"
b = "hello world, this is long"
print(a is b) # ❌ Может быть False
🔸 Никогда не полагайся на is для строк или чисел, если тебе важно только сравнение значений — используй ==.
🔹 Когда использовать is правильно?
✅ Используй is в следующих случаях:
1. Сравнение с None
if value is None:
print("Нет значения")
Почему не ==?
Потому что None — это единственный объект типа NoneType, и лучше сравнивать его через is, чтобы избежать ошибок с перегруженным _eq_.
2. Проверка на идентичность объектов
if a is b:
print("Это один и тот же объект")
🔹 Когда нельзя использовать is?
-
Никогда не используй is для сравнения строк, чисел, списков, кортежей, если тебе важны значения.
-
Даже если a is b случайно вернёт True — это не гарантировано в будущем или на другой платформе.
🔸 Перегрузка ==
Оператор == использует метод _eq_(), который можно переопределить в своих классах:
class Person:
def \__init_\_(self, name):
self.name = name
def \__eq_\_(self, other):
return self.name == other.name
p1 = Person("Alice")
p2 = Person("Alice")
print(p1 == p2) # ✅ True (сравнивает имена)
print(p1 is p2) # ❌ False (разные объекты)
🔹 Таблица сравнения is vs ==
Особенность | \== | is |
---|---|---|
Сравнивает | Значения | Идентичность объектов |
--- | --- | --- |
Результат | True, если содержимое совпадает | True, если ссылки совпадают |
--- | --- | --- |
Переопределяемый | Да (_eq_) | Нет |
--- | --- | --- |
Используется с None | Нет (нежелательно) | ✅ Да |
--- | --- | --- |
Для объектов одного типа | Да | Только если это один объект |
--- | --- | --- |
🔹 Заключение
Вопрос | Ответ |
---|---|
a == b | Сравнивает значения |
--- | --- |
a is b | Проверяет — это один и тот же объект? |
--- | --- |
Где is полезен? | Сравнение с None, проверка на идентичность |
--- | --- |
Где == предпочтительнее? | Во всех остальных случаях |
--- | --- |