Есть ли разница между "foo is None" и "foo == None"? - PullRequest
211 голосов
/ 25 августа 2008

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

if foo is None: pass

и

if foo == None: pass

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

Ответы [ 12 ]

249 голосов
/ 25 августа 2008

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

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

т.е.


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

>>> f = Foo()
>>> f == None
True
>>> f is None
False
48 голосов
/ 25 августа 2008

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

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

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

24 голосов
/ 26 августа 2008

Слово предостережения:

if foo:
  # do something

не точно так же, как:

if x is not None:
  # do something

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

12 голосов
/ 29 мая 2010

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

12 голосов
/ 25 февраля 2009

(ob1 is ob2) равно (id(ob1) == id(ob2))

8 голосов
/ 19 мая 2013

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

Сравнения с синглетами, такими как None, всегда должны выполняться с операторами is или not, никогда с операторами равенства.

7 голосов
/ 19 декабря 2014

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
4 голосов
/ 26 августа 2008

@ Jason

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

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

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

4 голосов
/ 25 августа 2008

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

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

Это вывело бы «Равно», так как списки имеют операцию сравнения, которая не является возвращением идентичности по умолчанию.

2 голосов
/ 19 мая 2013

Некоторые подробности:

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

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

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

1026 * Е.Г. *

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...