Есть ли какая-то разница между “foo is None” и “foo == None”?

StackOverflow https://stackoverflow.com/questions/26595

  •  09-06-2019
  •  | 
  •  

Вопрос

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

if foo is None: pass

и

if foo == None: pass

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

Это было полезно?

Решение

is всегда возвращается 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 в тестах с логическими значениями, например, пустые контейнеры, логические значения.В этой ситуации None также принимает значение false, но и другие вещи тоже принимают значение false.

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

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

Здесь нет никакой разницы, потому что объекты, которые идентичны, конечно, будут равны.Однако, БОДРОСТЬ ДУХА 8 четко указано, что вы должны использовать is:

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

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

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

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

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

@Джейсон:

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

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

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

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

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

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

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

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

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

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

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 


a = [1,3,4]
b = a[:] #creating copy of list
a is b # if gives false
False
a == b # gives true
True
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top