В чем разница между "is None" и "== None"?
Недавно я столкнулся с этой синтаксической конструкцией, но не понимаю, в чем разница.
Буду признателен, если кто-то объяснит мне разницу.
3 ответ(ов)
В приведенном вами коде класс Foo
переопределяет метод __eq__
, который отвечает за сравнение объектов на равенство. В частности, данный метод возвращает True
для любого значения, с которым сравнивается объект Foo
.
Вот что происходит в вашем коде:
class Foo:
def __eq__(self, other):
return True # Метод __eq__ возвращает True для всех сравнений
foo = Foo() # Создаем экземпляр класса Foo
print(foo == None) # Сравнение с None с помощью оператора ==
# Возвращает True, так как __eq__ возвращает True
print(foo is None) # Сравнение с None с помощью оператора is
# Возвращает False, потому что оператор is проверяет идентичность объектов, а не равенство
Таким образом, результатом выражения foo == None
будет True
, потому что метод __eq__
всегда возвращает True
. Однако выражение foo is None
вернет False
, так как оператор is
проверяет, указывают ли две переменные на один и тот же объект в памяти (в данном случае foo
и None
— это разные объекты).
Надеюсь, это проясняет ситуацию!
В данном случае они эквивалентны. None
— это объект-синглтон (существует только один экземпляр None
).
Оператор is
проверяет, являются ли два объекта одним и тем же объектом, в то время как ==
просто проверяет, эквивалентны ли они.
Например:
p = [1]
q = [1]
p is q # False, потому что это не один и тот же объект
p == q # True, потому что они эквивалентны
Но так как существует только один None
, они всегда будут одинаковыми, и is
вернет True.
p = None
q = None
p is q # True, потому что оба указывают на один и тот же "None"
Если вы используете numpy, выражение
if np.zeros(3) == None: pass
выдаст ошибку, так как numpy выполняет посElementoе сравнение. В данном случае np.zeros(3)
создает массив из трех нулей, и при сравнении с None
происходит попытка выполнить элементное сравнение значений, что не имеет смысла. Это приводит к возврату массива булевых значений, что в условии if
вызовет ошибку, так как ожидается логическое значение (True или False), а не массив.
Чтобы избежать этой ошибки, лучше использовать is None
для проверки на None
, например:
if np.zeros(3) is None: pass
Однако, это также будет всегда ложным, так как массив нулей никогда не будет равен None
. Если ваша цель — проверить, является ли массив пустым, можно использовать:
if np.zeros(3).size == 0: pass
Это проверит, что размер массива равен 0.
Как клонировать список, чтобы он не изменялся неожиданно после присваивания?
Преобразование списка словарей в DataFrame pandas
Ошибка: "'dict' объект не имеет метода 'iteritems'"
Как явно освободить память в Python?
Выбор строки из pandas Series/DataFrame по целочисленному индексу