Идентичность против равенства для None в Python - программирование
Подтвердить что ты не робот

Идентичность против равенства для None в Python

Различные руководства Python говорят использовать x is None вместо x == None. Почему это? Равенство используется для сравнения значений, поэтому естественно спросить, имеет ли x значение None, обозначенное ==, а не is. Может ли кто-нибудь объяснить, почему is является предпочтительной формой и показывает пример, где два не дают тот же ответ?

Спасибо.

4b9b3361

Ответ 1

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

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

print A() == None

Вывод:

True

Оператор is также быстрее, но я не считаю этот факт важным.

Ответ 2

Идентификатор ключевого слова is. Это не оператор сравнения, например ==. Использование is делает больше, чем проверка того, имеют ли два аргумента одно и то же значение и/или одну и ту же внутреннюю структуру: именно он проверяет, действительно ли эти два относятся к одному и тому же объекту в памяти. Есть много последствий для этого, один из которых заключается в том, что is не может быть перегружен, а другое - поведение, которое отличается от изменяемых и неизменяемых типов. Например, рассмотрим следующее:

>>> l1 = range(5)
>>> l2 = range(5)
>>> l1 == l2
True
>>> l1 is l2
False
>>> l3 = l1
>>> l1 is l3
True
>>> s1 = "abcde"
>>> s2 = "abcde"
>>> s1 == s2
True
>>> s1 is s2
True

Здесь, поскольку списки изменяемы, они не могут делить местоположение в памяти, и, следовательно, is и == дают несоответствующие результаты. С другой стороны, строки неизменяемы, и поэтому их память может быть объединена в некоторых случаях. В принципе, is можно надежно использовать только для простых, неизменяемых типов или в случаях, когда несколько имен указывают на один и тот же объект в памяти (например, использование l3 в приведенном выше примере), а его использование указывает на желание испытать идентичность, а не ценность. Я ожидал бы, что is будет немного быстрее, чем ==, потому что он не выполняет поиск метода, но я могу ошибаться. Конечно, для сложных объектов контейнера, таких как списки или dicts, is должен быть намного быстрее, чем == (O (1) против O (n), предположительно). Тем не менее, проблема скорости в основном спорная, поскольку эти два не следует рассматривать как взаимозаменяемые.

Ответ 3

PEP 8 говорит: "Сравнение с синглонами типа" Нет "всегда должно выполняться с помощью" есть "или" нет ", а не операторов равенства". Вот довольно хорошее объяснение, почему:

http://jaredgrubb.blogspot.com/2009/04/python-is-none-vs-none.html