Комментарии (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используй целенаправленно, когда действительно нужно проверить идентичность