Сравнение переменной с None в Python: использовать 'is' или '=='?
Быстрый ответ
В Python волей предпочтения для сравнения с None
следует использовать оператор is
, поскольку он оценивает идентичность объектов, что позволяет удостовериться, что переменная действительно имеет значение None
. Применение оператора ==
в этом контексте влечет за собой потенциальную опасность, так как пользовательские классы могут переопределять методы сравнения, изменяя заранее предполагаемое поведение.
Пример использования оператора is
:
if my_mystery_variable is None:
print("Дело решено, Шерлок Холмс! Это None!")
Погружение в детали: "is" против "=="
Очевидность "is" при сравнении с None
Неопределенность поведения "=="
Пользовательские классы как потенциальная ловушка
None
в Python — особенная константа, экземпляр которой единственен, подобно синглтону. Использование is
для сравнения с None
схоже с проверкой подлинности артефакта — быстро, безошибочно и точно.
Однако самое применение ==
подразумевает вопрос о равенстве содержимого относительно объектов. Пользовательские классы в Python могут интерпретировать равенство по-своему, вследствие чего ==
может возвращать значение истины даже в случаях, когда сравниваемое с None
ожидаемо ложно.
Сюрпризы от использования "is"
if the_prophecy is None:
# Пророчество пока не выполнилось, не будем торопить события.
print("Оракул пока молчит!")
None
, малые целочисленные значения и строковые литералы могут быть интернированы, поэтому существует только один объект, представляющий каждое из этих значений.
Проблемы с "==" и переопределением сравнения
class Amortentia:
def __eq__(self, other):
return other is None
love_potion = Amortentia()
if love_potion == None:
# Зелье усетило None и отреагировало на вызов.
print("Страсти накаляются!")
Согласно рекомендациям PEP 8, лучше избегать сравнения None
с использованием ==
.
Визуализация
# Сравнение с ==
🦔 == 🦔 # Может быть верно, если это один и тот же еж.
🦔 == 🌵 # Неверно, несмотря на кажущуюся схожесть между ними.
# Сравнение с is
🦔 is 🦔 # Истина, поскольку это один и тот же еж.
🦔 is 🌵 # Ложь, так как они суть разные.
Обобщая, следует использовать is
, чтобы удостовериться в сравнении с None
.
hedgehog = None
cactus = None
if hedgehog is None:
print("Ежу тоже нужна доза любви!")
Оператор is
позволяет точно определить None
, в то время как ==
время от времени может создавать иллюзии, которые в Python недолго длится.
Случаи, когда "is" может сбить с толку
Особенности сравнения целых чисел
Ошибки с изменяемыми объектами
Пользовательские синглтоны
Оператор is
не без своих ограничений и может ввести в заблуждение при сравнении изменяемых объектов и целых чисел, выходящих за пределы диапазона интернирования.
Заблуждения целых чисел
Целые числа вне диапазона [-5, 256], в отличие от None
, при сравнении с использованием is
могут давать непредсказуемый результат:
magic_number = 257
another_number = 257
print(magic_number is another_number) # Может вывести False!
С изменяемыми объектами лучше всего сравнивать их значения, а не идентичность.
Одиночественность пользовательских синглтонов
is
подходит для работы с синглтонами, включая пользовательские, точно так же, как и с None
:
class SingletonCalendar(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class WeasleyFamilyCalendar(metaclass=SingletonCalendar):
pass
weasley_calendar = WeasleyFamilyCalendar()
another_calendar = WeasleyFamilyCalendar()
if weasley_calendar is another_calendar:
print("Расписанием квиддича не упустить!")
Полезные материалы
- PEP 8 – Руководство по стилю написания кода на Python — лучшие практики для сравнения с
None
в Python. - Python '!=' и 'is not': Сравнение объектов в Python – Real Python — разница между идентичностью и равенством.
- Когда следует использовать "is None" вместо "== None" — обсуждение на Stack Overflow.
- Имена и значения в Python | Ned Batchelder — оператор 'is' и семантика переменных.
- 6. Выражения — официальная документация Python 3.12.2 — использование 'is' и '=='.
- Разница между "==" и "is" (Равенство против Идентичности) – YouTube — видео на YouTube, разъясняющее практическое применение '==' и 'is'.
- Is против Equals – Python Wiki — подробное объяснение 'is' в противостоянии с '=='.