ПРИХОДИТЕ УЧИТЬСЯ НОВОЙ ПРОФЕССИИ ЛЕТОМ СО СКИДКОЙ ДО 70%Забронировать скидку

Сравнение переменной с None в Python: использовать 'is' или '=='?

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

В Python волей предпочтения для сравнения с None следует использовать оператор is, поскольку он оценивает идентичность объектов, что позволяет удостовериться, что переменная действительно имеет значение None. Применение оператора == в этом контексте влечет за собой потенциальную опасность, так как пользовательские классы могут переопределять методы сравнения, изменяя заранее предполагаемое поведение.

Пример использования оператора is:

Python
Скопировать код
if my_mystery_variable is None:
    print("Дело решено, Шерлок Холмс! Это None!")
Пройдите тест и узнайте подходит ли вам сфера IT
Пройти тест

Погружение в детали: "is" против "=="

Очевидность "is" при сравнении с None

Неопределенность поведения "=="

Пользовательские классы как потенциальная ловушка

None в Python — особенная константа, экземпляр которой единственен, подобно синглтону. Использование is для сравнения с None схоже с проверкой подлинности артефакта — быстро, безошибочно и точно.

Однако самое применение == подразумевает вопрос о равенстве содержимого относительно объектов. Пользовательские классы в Python могут интерпретировать равенство по-своему, вследствие чего == может возвращать значение истины даже в случаях, когда сравниваемое с None ожидаемо ложно.

Сюрпризы от использования "is"

Python
Скопировать код
if the_prophecy is None:
    # Пророчество пока не выполнилось, не будем торопить события.
    print("Оракул пока молчит!")

None, малые целочисленные значения и строковые литералы могут быть интернированы, поэтому существует только один объект, представляющий каждое из этих значений.

Проблемы с "==" и переопределением сравнения

Python
Скопировать код
class Amortentia:
    def __eq__(self, other):
        return other is None

love_potion = Amortentia()
if love_potion == None:  
    # Зелье усетило None и отреагировало на вызов.
    print("Страсти накаляются!")

Согласно рекомендациям PEP 8, лучше избегать сравнения None с использованием ==.

Визуализация

Markdown
Скопировать код
# Сравнение с ==
🦔 == 🦔  # Может быть верно, если это один и тот же еж.
🦔 == 🌵  # Неверно, несмотря на кажущуюся схожесть между ними.

# Сравнение с is
🦔 is 🦔  # Истина, поскольку это один и тот же еж.
🦔 is 🌵  # Ложь, так как они суть разные.

Обобщая, следует использовать is, чтобы удостовериться в сравнении с None.

Markdown
Скопировать код
hedgehog = None
cactus = None

if hedgehog is None:
    print("Ежу тоже нужна доза любви!")

Оператор is позволяет точно определить None, в то время как == время от времени может создавать иллюзии, которые в Python недолго длится.

Случаи, когда "is" может сбить с толку

Особенности сравнения целых чисел

Ошибки с изменяемыми объектами

Пользовательские синглтоны

Оператор is не без своих ограничений и может ввести в заблуждение при сравнении изменяемых объектов и целых чисел, выходящих за пределы диапазона интернирования.

Заблуждения целых чисел

Целые числа вне диапазона [-5, 256], в отличие от None, при сравнении с использованием is могут давать непредсказуемый результат:

Python
Скопировать код
magic_number = 257
another_number = 257
print(magic_number is another_number)  # Может вывести False!

С изменяемыми объектами лучше всего сравнивать их значения, а не идентичность.

Одиночественность пользовательских синглтонов

is подходит для работы с синглтонами, включая пользовательские, точно так же, как и с None:

Python
Скопировать код
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("Расписанием квиддича не упустить!")

Полезные материалы

  1. PEP 8 – Руководство по стилю написания кода на Python — лучшие практики для сравнения с None в Python.
  2. Python '!=' и 'is not': Сравнение объектов в Python – Real Python — разница между идентичностью и равенством.
  3. Когда следует использовать "is None" вместо "== None" — обсуждение на Stack Overflow.
  4. Имена и значения в Python | Ned Batchelder — оператор 'is' и семантика переменных.
  5. 6. Выражения — официальная документация Python 3.12.2 — использование 'is' и '=='.
  6. Разница между "==" и "is" (Равенство против Идентичности) – YouTube — видео на YouTube, разъясняющее практическое применение '==' и 'is'.
  7. Is против Equals – Python Wiki — подробное объяснение 'is' в противостоянии с '=='.