Есть ли разница между:
if foo is None: pass
и
if foo == None: pass
Соглашение, которое я видел в большей части кода Python (и кода, который я сам пишу), является первым, но недавно я наткнулся на код, который использует последний. Ни один не является экземпляром (и единственным экземпляром, IIRC) NoneType, так что это не должно иметь значения, верно? Существуют ли обстоятельства, при которых это может произойти?
is
оператор не может быть настроен (перегружен определяемым пользователем классом).__eq__(self)
- это специальный встроенный метод, который определяет, как==
обрабатывается при использовании объекта Python. Здесь мы переопределили это так, что когда==
оно используется для объектов типа,Foo
оно всегда возвращает true. Дляis
оператора не существует эквивалентного метода, и поэтому поведениеis
нельзя изменить таким же образом.Вы можете прочитать этот объект идентичности и эквивалентности .
Оператор «is» используется для идентификации объекта, он проверяет, ссылаются ли объекты на один и тот же экземпляр (тот же адрес в памяти).
И выражение «==» относится к равенству (то же значение).
источник
a=1;b=1;print(a is b) # True
. Есть идеи, почему ониa is b
оказываются правдой, даже если они кажутся двумя разными объектами (разные адреса в памяти)?Слово предостережения:
Это не то же самое, что:
Первый из них является тестом логического значения и может принимать значение false в разных контекстах. Есть несколько вещей, которые представляют ложь в тестах логических значений, например, пустые контейнеры, логические значения. Никто также не оценивает ложь в этой ситуации, но другие вещи тоже.
источник
(ob1 is ob2)
равно(id(ob1) == id(ob2))
источник
is
версия не нуждается в вызове функции, и не поиск атрибута питона-интерпретатора на всех; интерпретатор может немедленно ответить, если ob1 фактически является ob2.{} is {}
ложно иid({}) == id({})
может быть (и находится в CPython) истиной. См. Stackoverflow.com/questions/3877230Причина в
foo is None
том, что предпочтительным способом является то, что вы можете обрабатывать объект, который определяет его собственный__eq__
, и который определяет объект равным None. Так что всегда используйте,foo is None
если вам нужно увидеть, если это на самом делеNone
.источник
Нет никакой разницы, потому что объекты, которые идентичны, конечно, будут равны. Однако в PEP 8 четко указано, что вы должны использовать
is
:источник
is
тесты на идентичность, а не равенство. Для вашего утвержденияfoo is none
Python просто сравнивает адрес памяти объектов. Это означает, что вы задаете вопрос "У меня есть два имени для одного и того же объекта?"==
с другой стороны, проверяет равенство, определяемое__eq__()
методом. Это не заботится о личности.None
является одноэлементным оператором. ТакNone is None
всегда и есть.источник
Для None не должно быть разницы между равенством (==) и идентичностью (есть). NoneType, вероятно, возвращает идентичность для равенства. Поскольку None - это единственный экземпляр, который вы можете создать из NoneType (я думаю, что это правда), эти две операции одинаковы. В случае других типов это не всегда так. Например:
Это напечатало бы «Равно», так как списки имеют операцию сравнения, которая не является возвращением идентичности по умолчанию.
источник
@ Джейсон :
Я не люблю использовать «if foo:», если foo действительно не представляет логическое значение (то есть 0 или 1). Если foo является строкой или объектом или чем-то еще, «if foo:» может работать, но для меня это выглядит как ленивый ярлык. Если вы проверяете, является ли x значением None, скажите «если x равен None:».
источник
if foo
вернет false и комментарий#foo is None
будет неверным.Еще несколько деталей:
Предложение
is
фактически проверяет,object
находятся ли два элемента в одной и той же ячейке памяти или нет. то есть указывают ли они на одну и ту же ячейку памяти и имеют ли они одинаковое значениеid
.Как следствие 1,
is
гарантирует, имеют ли два лексически представленныхobject
s идентичные атрибуты (атрибуты-атрибуты ...) или нетИнстанцирование примитивных типов , таких как
bool
,int
,string
(с некоторым исключением),NoneType
имеющий то же значение всегда будет в том же месте памяти.Например
И поскольку
NoneType
в «поисковой» таблице Python может быть только один экземпляр самого себя, то первый и второй являются скорее стилем программирования разработчика, который написал код (возможно, для согласованности), а не имеют какой-либо тонкой логической причины выберите один над другим.источник
some_string is "bar"
для сравнения строк НИКОГДА. Это НЕ ЕДИНСТВЕННАЯ ПРИЕМНАЯ ПРИЧИНА, чтобы сделать это, и она сломается, когда вы этого не ожидаете. Факт, что это работает часто, просто потому, что CPython знает, что было бы глупо создавать два неизменных объекта, которые имеют одинаковое содержимое. Но это все же может случиться.int
верно?Вывод Джона Мачина о том, что он
None
является единичным, является заключением, подкрепленным этим кодексом.Так
None
как это единственный,x == None
иx is None
будет иметь тот же результат. Однако, по моему эстетическому мнению,x == None
лучше всего.источник
None
объектом. Для сравнения, редко можно увидеть, что None используется в любом другом контексте, за исключением того, что он похож наFalse
другие ценности, которые являются правдивыми. В этих случаях более идиоматично делать что-то вродеif x: pass
источник