← Назад к вопросам
Как понять, что один объект идентичен другому объекту в Python?
1.0 Junior🔥 91 комментариев
#Soft Skills
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как понять, что один объект идентичен другому в Python
Это про разницу между == и is — часто путают даже опытные разработчики.
Различие: == vs is
- == сравнивает значения (использует метод eq)
- is сравнивает идентичность (адреса в памяти)
# Пример 1: Числа
a = 10
b = 10
print(a == b) # True — значения одинаковые
print(a is b) # True — в Python -5...256 кешируются
# Но с большими числами:
a = 257
b = 257
print(a == b) # True
print(a is b) # False! Разные объекты
# Пример 2: Списки
list1 = [1, 2, 3]
list2 = [1, 2, 3]
print(list1 == list2) # True — одинаковое содержимое
print(list1 is list2) # False — разные объекты
list3 = list1
print(list3 == list1) # True
print(list3 is list1) # True — одна и та же ссылка
Когда использовать is
Правильно используй is только для:
1. Сравнение с None:
if value is None: # Правильно
pass
if value == None: # Не рекомендуется
pass
2. Сравнение с True/False:
if value is True: # Для проверки точно True
pass
if value: # Обычно просто value
pass
3. Проверка идентичности объектов:
class User:
pass
user1 = User()
user2 = User()
print(user1 == user2) # False
print(user1 is user2) # False
user3 = user1
print(user1 is user3) # True
Метод eq: переопределение сравнения
class User:
def __init__(self, user_id: int, name: str):
self.user_id = user_id
self.name = name
def __eq__(self, other):
if not isinstance(other, User):
return False
return self.user_id == other.user_id
def __hash__(self):
return hash(self.user_id)
user1 = User(1, 'Alice')
user2 = User(1, 'Alice')
user3 = User(2, 'Bob')
print(user1 == user2) # True — user_id одинаковый
print(user1 is user2) # False — разные объекты
print(user1 == user3) # False
Практический пример: Django модели
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
def __eq__(self, other):
if not isinstance(other, Article):
return False
if self.pk is None or other.pk is None:
return self is other
return self.pk == other.pk
article1 = Article.objects.get(id=1)
article2 = Article.objects.get(id=1)
print(article1 == article2) # True — одна запись
print(article1 is article2) # False — разные объекты
Глубокое сравнение vs поверхностное
# Поверхностное
class Person:
def __init__(self, name: str, address: dict):
self.name = name
self.address = address
person1 = Person('Alice', {'city': 'NYC'})
person2 = Person('Alice', {'city': 'NYC'})
print(person1 == person2) # False
print(person1.name == person2.name and person1.address == person2.address) # True
# Глубокое
import copy
person3 = copy.deepcopy(person1)
person3.address['city'] = 'LA'
print(person1.address == person3.address) # False
Проверка идентичности с id()
list1 = [1, 2, 3]
list2 = [1, 2, 3]
print(id(list1)) # Адрес в памяти
print(id(list2)) # Адрес в памяти
print(id(list1) == id(list2)) # False
list3 = list1
print(id(list1) == id(list3)) # True
Кеширование объектов в Python
# Python кеширует маленькие числа
a = 5
b = 5
print(a is b) # True
# Строки тоже кешируются
s1 = 'hello'
s2 = 'hello'
print(s1 is s2) # Обычно True
# Но после конкатенации:
s3 = 'hel' + 'lo'
print(s3 is s1) # False
# Поэтому для строк всегда используй ==
if s1 == s3: # Правильно
pass
Практические рекомендации
Правильно:
if user is None: # Проверка с None
pass
if items: # Проверка пустоты
pass
if obj == other_obj: # Сравнение значений
pass
Неправильно:
if user == None: # Используй is None
pass
if user is not None and user == some_value:
pass
Как работает сравнение в списках и словарях
users = [User(1, 'Alice'), User(2, 'Bob')]
user_alice = User(1, 'Alice')
print(user_alice in users) # Использует == для поиска
# Словари используют __hash__ и __eq__
user_dict = {User(1, 'Alice'): 'active'}
# Поиск по ключу использует hash() и ==
Итоговое резюме
- Используй == для сравнения значений
- Используй is только для None, True/False
- Переопределяй eq если нужно кастомное сравнение
- Если переопределяешь eq, определи и hash
- Для проверки идентичности используй is
- Python кеширует маленькие числа и строки (это деталь реализации)