← Назад к вопросам

Как понять, что один объект идентичен другому объекту в 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 кеширует маленькие числа и строки (это деталь реализации)
Как понять, что один объект идентичен другому объекту в Python? | PrepBro