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

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

1.0 Junior🔥 291 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между == и is

Это один из фундаментальных вопросов в Python, касающихся сравнения объектов. Оба оператора выполняют сравнение, но работают они совершенно по-разному.

Определение

Оператор == (равенство по значению)

== сравнивает значения объектов. Он проверяет, содержат ли объекты одинаковые данные.

a = [1, 2, 3]
b = [1, 2, 3]

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

Оператор == вызывает магический метод __eq__ и зависит от его реализации в классе:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __eq__(self, other):
        if not isinstance(other, Person):
            return False
        return self.name == other.name and self.age == other.age

alice1 = Person('Alice', 30)
alice2 = Person('Alice', 30)
bob = Person('Bob', 25)

print(alice1 == alice2)  # True (определено в __eq__)
print(alice1 == bob)     # False
print(alice1 is alice2)  # False (разные объекты)

Оператор is (идентичность)

is сравнивает идентичность объектов, т.е. указывают ли переменные на один и тот же объект в памяти. Он проверяет адреса объектов в памяти (id).

a = [1, 2, 3]
b = a  # b ссылается на тот же объект
c = [1, 2, 3]  # новый объект

print(a is b)  # True (один и тот же объект)
print(a is c)  # False (разные объекты)
print(id(a) == id(b))  # True
print(id(a) == id(c))  # False

Наглядное сравнение

# Примитивы и интерны
print(1 == 1)    # True
print(1 is 1)    # True (Python кэширует маленькие целые числа)

print('hello' == 'hello')    # True
print('hello' is 'hello')    # True (интернирование строк)

print([] == [])    # True (одинаковые значения)
print([] is [])    # False (разные объекты)

# None (специальный случай)
print(None is None)   # True (существует только один None)
print(None == None)   # True

Производительность

is работает быстрее, чем ==, потому что просто сравнивает адреса в памяти:

import timeit

# Сравнение производительности
setup = 'a = [1, 2, 3] * 1000; b = a'

time_is = timeit.timeit('a is b', setup, number=1000000)
time_eq = timeit.timeit('a == b', setup, number=1000000)

print(f'is: {time_is:.4f}s')
print(f'==: {time_eq:.4f}s')
# is примерно в 3-5 раз быстрее

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

1. Сравнение с None

# Правильно
if value is None:
    pass

# Неправильно
if value == None:
    pass

2. Сравнение с True/False

# Правильно
if is_active is True:
    pass

# Лучше просто
if is_active:
    pass

# Неправильно
if is_active == True:
    pass

3. Проверка на то же самое существование

original_list = [1, 2, 3]
reference = original_list

# Проверяем, что это один и тот же объект
if reference is original_list:
    print("Это один и тот же объект")

4. Проверка싱글тона

class DatabaseConnection:
    _instance = None
    
    @classmethod
    def get_instance(cls):
        if cls._instance is None:
            cls._instance = cls()
        return cls._instance

db1 = DatabaseConnection.get_instance()
db2 = DatabaseConnection.get_instance()

print(db1 is db2)  # True (один синглтон)

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

1. Сравнение значений

if user_input == 'yes':
    proceed()

if age == 18:
    is_adult()

2. Сравнение контейнеров

config_expected = {'host': 'localhost', 'port': 5432}
config_actual = get_config()

if config_expected == config_actual:
    print("Конфиг корректен")

3. Сравнение объектов (когда реализован eq)

user1 = User(id=1, name='Alice')
user2 = User(id=1, name='Alice')
user3 = User(id=2, name='Bob')

if user1 == user2:
    print("Один и тот же пользователь")

if user1 != user3:
    print("Разные пользователи")

Особенности Python

Интернирование объектов

Python оптимизирует память, кэшируя некоторые объекты:

# Малые целые числа (-5 до 256)
a = 256
b = 256
print(a is b)  # True (кэшировано)

a = 257
b = 257
print(a is b)  # Обычно False, но может быть True в REPL

# Строки (интернирование)
s1 = 'hello'
s2 = 'hello'
print(s1 is s2)  # Обычно True

# Но не всегда
s3 = ''.join(['h', 'e', 'l', 'l', 'o'])
print(s1 is s3)  # False (создано динамически)

Таблица сравнения

ОператорСравниваетСкоростьИспользование
==ЗначенияМедленнееПроверка данных
isИдентичностьБыстрееNone, синглтоны

Практический пример

def validate_request(data):
    # Правильно: проверяем значение
    if data.get('status') == 'active':
        return True
    
    # Правильно: проверяем отсутствие
    if data.get('error') is None:
        return True
    
    # Неправильно: медленно и непитоническо
    if data.get('count') is 0:
        return False
    
    # Правильно
    if data.get('count') == 0:
        return False
    
    return False

def process_database():
    connection = get_connection()
    
    try:
        result = connection.query()
        # Правильно: проверяем на None
        if result is not None:
            return result
    finally:
        if connection is not None:
            connection.close()

Заключение

Золотое правило:

  • Используй == для сравнения значений
  • Используй is для сравнения с None, True, False или проверки идентичности объектов
  • В 99% случаев тебе нужен ==
  • is используй целенаправленно, когда действительно нужно проверить идентичность
В чем разница между == и is? | PrepBro