Есть ли разница между «foo is None» и «foo == None»?

Есть ли разница между:

if foo is None: pass 

а также

 if foo == None: pass 

Соглашение, которое я видел в большинстве Python-кода (и код, который я сам пишу), является первым, но я недавно натолкнулся на код, который использует последний. None – это экземпляр (и единственный экземпляр, IIRC) NoneType, поэтому это не имеет значения, не так ли? Существуют ли какие-либо обстоятельства, в которых это возможно?

11 Solutions collect form web for “Есть ли разница между «foo is None» и «foo == None»?”

всегда возвращает значение True если он сравнивает один и тот же экземпляр объекта

В то время как == в конечном итоге определяется методом __eq__()

т.е.

 >>> class Foo(object): def __eq__(self, other): return True >>> f = Foo() >>> f == None True >>> f is None False 

Возможно, вам захочется прочитать идентификатор этого объекта и его эквивалентность .

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

И выражение '==' относится к равенству (то же значение).

Предупреждение:

 if foo: # do something 

Не совсем то же самое, что:

 if x is not None: # do something 

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

(ob1 is ob2) равный (id(ob1) == id(ob2))

Причина, по которой foo is None является предпочтительным способом – вы можете обрабатывать объект, который определяет свой собственный __eq__ , и который определяет объект равным None. Таким образом, всегда использовать foo is None если вам нужно посмотреть, не является ли оно infact None .

Нет никакой разницы, потому что идентичные объекты, конечно, будут равны. Однако в PEP 8 четко указано, что вы должны использовать:

Сравнение с синглонами типа «Нет» всегда должно выполняться с помощью или нет, а не с операторами равенства.

Для None не должно быть разницы между равенством (==) и identity (is). Вероятно, NoneType возвращает идентификатор для равенства. Поскольку None – единственный экземпляр, который вы можете сделать из NoneType (я думаю, что это правда), две операции одинаковы. В случае других типов это не всегда так. Например:

 list1 = [1, 2, 3] list2 = [1, 2, 3] if list1==list2: print "Equal" if list1 is list2: print "Same" 

Это напечатает «Equal», поскольку в списках есть операция сравнения, которая не является возвратом идентичности по умолчанию.

@ Джейсон :

Я рекомендую использовать что-то более

 if foo: #foo isn't None else: #foo is None 

Мне не нравится использовать «if foo:», если foo действительно не представляет собой логическое значение (то есть 0 или 1). Если foo – это строка или объект или что-то еще, «если foo:» может работать, но это выглядит ленивым ярлыком для меня. Если вы проверяете, является ли x None, скажите «если x – None:».

is тесты для идентичности, а не равенства. Для вашего утверждения foo is none , Python просто сравнивает адрес памяти объектов. Это означает, что вы задаете вопрос «У меня есть два имени для одного и того же объекта?»

== другой стороны, тесты для равенства определяются методом __eq__() . Он не заботится о личности.

 In [102]: x, y, z = 2, 2, 2.0 In [103]: id(x), id(y), id(z) Out[103]: (38641984, 38641984, 48420880) In [104]: x is y Out[104]: True In [105]: x == y Out[105]: True In [106]: x is z Out[106]: False In [107]: x == z Out[107]: True 

None является одиночным оператором. Так что None is None – это всегда правда.

 In [101]: None is None Out[101]: True 

Вывод Джона Мачина о том, что None является синглом, – это заключение, подкрепленное этим кодом.

 >>> x = None >>> y = None >>> x == y True >>> x is y True >>> 

Поскольку None – одноэлементный, x == None и x is None , тот же результат. Однако, по моему эстетическому мнению, x == None лучше.

Еще несколько деталей:

  1. Предложение is фактически проверяет, находятся ли два object s в одном и том же месте памяти или нет. т.е. оба они указывают на одно и то же место памяти и имеют одинаковый id .

  2. Как следствие 1, обеспечивается ли или нет, два лексически представленных object s имеют одинаковые атрибуты (атрибуты-атрибуты …) или нет

  3. Инстанцирование примитивных типов, таких как bool , int , string (с некоторым исключением), NoneType с одинаковым значением всегда будет находиться в одном и том же месте памяти.

Например

 >>> int(1) is int(1) True >>> str("abcd") is str("abcd") True >>> bool(1) is bool(2) True >>> bool(0) is bool(0) True >>> bool(0) False >>> bool(1) True 

И поскольку у NoneType может быть только один экземпляр самого себя в таблице поиска «python», поэтому первая и последняя являются скорее стилем программирования разработчика, который написал код (возможно, для согласованности), а затем имеет любую тонкую логическую причину выбирать один над другим.

  • Нормально ли для python io.BytesIO.getvalue () возвращать str вместо байтов?
  • Как записать имена, начинающиеся с A - L, в один файл, а остальные - на другой?
  • Лучший способ доступа к методу суперкласса при множественном наследовании
  • Инициализировать макет проекта в python?
  • сравнение списков python
  • Получить тип данных, хранящихся в строке в python
  • Как преобразовать временную строку в Google AppEngine db.TimeProperty?
  • Правильная печать функций Выход и отсутствие
  •  
    Interesting Posts for Van-Lav

    возвращает список слов после чтения файла в python

    Решение работает для выборочных данных, но онлайн-судья дает ошибки?

    FFMpeg пишет анимацию matplotlib с уменьшающимся качеством

    Как объекты QApplication () и QWidget () подключены в PySide / PyQt?

    перевести мою последовательность?

    Когда установлен набор локальных локаторов?

    Использование как matplotlib, так и rpy2 с многострочными пакетами на Heroku

    TCP-сервер / клиент: Сломанная труба

    Подавление префиксов пространства имен в ElementTree 1.2

    Кривая для нормального распределения в Python

    понимание python скрученной асинхронности с точки зрения операционной системы

    Как использовать __getitem__ и __iter__ и возвращать значения из словаря?

    Как применять границы max & min к значению без использования условных операторов

    узлы метки снаружи с минимальным перекрытием с другими узлами / ребрами в networkx

    Как установить mysqlDb для MySQL и Python в Windows

    Python - лучший язык программирования в мире.