14. Проверить равенства и идентичности объектов
Условие задачи Какой результат будет выведен на экран при выполнении данного кода?
class FooCollection:
foo_1 = int("2" + "2") == int("22")
foo_2 = int("22" + "22") == int("2222")
foo_3 = int("2" + "2") is int("22")
foo_0 = int("22" + "22") is int("2222")
print(all([getattr(FooCollection(), f"foo_{x}") for x in range(4)])) >>
Спойлеры к решению
Подсказки
- Оператор
==сравнивает значения. - Оператор
isсравнивает идентичность объектов в памяти. foo_1иfoo_2будутTrue, потому что значения чисел одинаковые.foo_3в CPython обычно будетTrue, потому что маленькие целые числа кэшируются.foo_0обычно будетFalse, потому что2222не входит в стандартный диапазон кэшируемых маленьких чисел.all()вернётTrueтолько если все элементы списка истинные.
Решение
class FooCollection:
foo_1 = int("2" + "2") == int("22")
foo_2 = int("22" + "22") == int("2222")
foo_3 = int("2" + "2") is int("22")
foo_0 = int("22" + "22") is int("2222")
print(all([getattr(FooCollection(), f"foo_{x}") for x in range(4)]))
Результат:
False
Разбор:
foo_1 = int("2" + "2") == int("22")
"2" + "2" даёт строку "22", поэтому сравнение превращается в:
22 == 22
Результат:
True
Дальше:
foo_2 = int("22" + "22") == int("2222")
"22" + "22" даёт строку "2222", поэтому:
2222 == 2222
Результат:
True
Дальше:
foo_3 = int("2" + "2") is int("22")
В CPython маленькие целые числа обычно кэшируются. Число 22 относится к таким числам, поэтому оба выражения могут ссылаться на один и тот же объект.
Результат в CPython:
True
Дальше:
foo_0 = int("22" + "22") is int("2222")
Значение 2222 одинаковое, но это уже не маленькое кэшируемое число. Поэтому два вызова int() обычно создают разные объекты.
Результат в CPython:
False
Затем выполняется:
[getattr(FooCollection(), f"foo_{x}") for x in range(4)]
Это даёт список:
[foo_0, foo_1, foo_2, foo_3]
То есть:
[False, True, True, True]
Поэтому:
all([False, True, True, True])
вернёт:
False
Важно: для чисел нужно использовать ==, а не is. Оператор is проверяет не равенство значений, а то, являются ли две ссылки одним и тем же объектом.