Есть ли разница между "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