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

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

if foo is None: pass

и

if foo == None: pass

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

Ответ 1

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

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

то есть.


>>> class Foo(object):
       def __eq__(self, other):
           return True

>>> f = Foo()
>>> f == None
True
>>> f is None
False

Ответ 2

Вы можете прочитать этот идентификатор и эквивалентность объекта.

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

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

Ответ 3

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

if foo:
  # do something

Является не точно так же, как:

if x is not None:
  # do something

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

Ответ 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"

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

Ответ 9

@Джейсон:

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

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

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

Ответ 10

Дополнительная информация:

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

  • Как результат 1, is гарантирует, что или нет, два лексически представленных object имеют одинаковые атрибуты (атрибуты-атрибуты...) или нет

  • Активация примитивных типов, таких как 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", поэтому первая и последняя являются скорее стилем программирования разработчика, который написал код (возможно, для согласованности), а затем имея любую тонкую логическую причину выбора одного над другим.

Ответ 11

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

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

Так как None - одноэлементный, x == None и x is None будут иметь одинаковый результат. Однако, по моему эстетическому мнению, лучше всего x == None.

Ответ 12

a is b # returns true if they a and b are true alias
a == b # returns true if they are true alias or they have values that are deemed equivalence