Python Нет сравнения: я должен использовать «есть» или ==?


213

Мой редактор предупреждает меня, когда я сравниваю my_var == None, но не предупреждает, когда я использую my_var is None.

Я провел тест в оболочке Python и определил, что оба кода являются допустимыми, но мой редактор, кажется, говорит, что my_var is Noneэто предпочтительнее.

Так ли это, и если да, то почему?


7
PEP-где - то говорит , что вы должны сравнить одиночка с использованием is- python.org/dev/peps/pep-0008/#programming-recommendations
Волатильность

2
Этот постер говорит о Python 3, а мой вопрос о Python 2.x. Я не уверен, является ли это достаточно большой разницей, чтобы оправдать оба оставшихся, но я отредактировал вопрос, чтобы включить это на всякий случай.
Клэй Уорделл

2
Я не думаю, что этот вопрос действительно дубликат. Другой был о == vs в общем, этот о None в частности.
IJ Кеннеди

Ответы:


254

Резюме:

Используйте, isкогда вы хотите проверить идентичность объекта (например, проверить, если varесть None). Используйте, ==когда вы хотите проверить равенство (например, varравно 3?).

Объяснение:

Вы можете иметь пользовательские классы, где my_var == Noneбудут возвращатьсяTrue

например:

class Negator(object):
    def __eq__(self,other):
        return not other

thing = Negator()
print thing == None    #True
print thing is None    #False

isпроверяет идентичность объекта . Существует только 1 объект None, поэтому, когда вы это делаете my_var is None, вы проверяете, являются ли они на самом деле одним и тем же объектом (а не просто эквивалентными объектами)

Другими словами, ==это проверка на эквивалентность (которая определяется от объекта к объекту), тогда как isпроверка на идентичность объекта:

lst = [1,2,3]
lst == lst[:]  # This is True since the lists are "equivalent"
lst is lst[:]  # This is False since they're actually different objects

23
Когда is Noneотличается от == None?
Блендер

11
@Blender В упомянутом случае. __eq__может быть определена любым способом, но поведение isне может быть так легко изменено.
Лев Левицкий

5
@LevLevitsky: Одним из примеров использования Mython было «расширение протоколов, чтобы любой оператор мог быть перегружен, даже is». После комментария к спискам он изменил это на «… даже is(но только если вы ненормальный)».
abarnert

1
+1, но было бы еще лучше, если бы в этом ответе содержалась ссылка на PEP 8, которую делают другие (а также объяснение того, почему решение за PEP 8 имеет смысл, что оно и так делает).
abarnert

3
@abarnert - я даже не знал, что ПКП 8 вынесла рекомендацию здесь. Дело в том, что это разные операторы, которые делают разные вещи. Могут быть случаи, когда на object == Noneсамом деле это правильная идиома (хотя я не могу думать ни о чем из головы). Вам просто нужно знать, что вы делаете.
Мгилсон

127

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

Эта рекомендация поддерживается в PEP 8 , в которой прямо говорится, что «сравнение с синглетами, такими как None, всегда должно выполняться с использованием операторов равенства, isили is notникогда с ними».


6
Спасибо за публикацию этого; Принятый ответ делает некоторые интересные моменты, но ваш ответ на вопрос гораздо более прямо.
Люк Дэвис,

Кажется странным полагаться на то, что по существу является деталью реализации. Почему меня должно волновать количество экземпляров NoneType?
BallpointBen

@BallpointBen Потому что это не деталь реализации - Noneпод глобальной константой есть только один объект None. Во всяком случае, NoneTypeэто деталь реализации, потому что Noneсинглтон должен иметь некоторый тип. (Тот факт, что вы не можете создавать экземпляры этого типа, является хорошим свидетельством того, что один его экземпляр предназначен для использования в качестве
одиночного

@BallpointBen Я думаю, что ключевым моментом является то, что Python обладает четкой концепцией идентичности объектов. Если вы хотите проверить , сравнивает ли объект , равный To None, все средства использовать obj == None. Если вы хотите проверить , является ли объект является None использовать obj is None. Суть рекомендации PEP 8 (и этого ответа) заключается в том, что большинство людей хотят последнее, когда хотят проверить None, и это также оказывается быстрее и понятнее.
user4815162342

Noneтакже отличается от кэшируемых объектов, таких как 0и другие маленькие целые числа, где кэширование действительно является деталью реализации. Разница в том, что целое число имеет внутреннее значение, которое дает его свойства, и его можно вычислить. С другой стороны, Noneне имеет государства вообще, имеет значение только его личность и делает его особенным.
user4815162342

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.