С каких это пор Python None равен None?

Я всегда думал, что нули Python не равны, как это принято во многих других языках и основано на простой логике (если значение неизвестно, как оно может быть равно другому неизвестному?).

Однако недавно я попробовал это и обнаружил, что:

Python 3.10.2
>>> None == None
True

Всегда ли так было? Если нет, то в какой версии это изменилось?

Я не путаю это с NaN, @Barmar, вопрос о None, а не о NaN. На самом деле я думал о таких вещах, как SQL NULL.

Dommondke 31.03.2023 21:45

Я несколько удивлен, что в официальной документации None по-прежнему упоминается как «Нулевой объект».

chepner 31.03.2023 21:47

SQL NULL подобен NaN. Python Нет.

Barmar 31.03.2023 21:48

Очевидно, это так, основываясь на ответе на мой вопрос, который фактически спрашивает, похож ли Python None на SQL NULL...

Dommondke 31.03.2023 21:49
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
61
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Никто не всегда был равен самому себе в питоне. «Нет == Нет» всегда оценивается как истина.

Как видно из этой документации https://docs.python.org/3/c-api/none.html

Поскольку None является синглтоном, достаточно проверить идентичность объекта (используя == в C).

Не то чтобы я вам не верил, но есть ли у вас ссылка на то, где это определено в спецификации языка?

Dommondke 31.03.2023 21:39

Конечно, если не указано иное, вы ожидаете, что все значения будут равны сами себе.

kindall 31.03.2023 21:40
docs.python.org/3/c-api/none.html отметьте «Объект None»
Caleb Carson 31.03.2023 21:42

@CalebCarson: на самом деле это ничего не говорит о том, как None ведет себя при сравнении Python ==. Он делает краткую ссылку на совершенно другой оператор C ==, но ничего не говорит о Python ==.

user2357112 31.03.2023 21:43

@ user2357112, конечно, вы могли бы явно задокументировать противоположное поведение в Python, не противоречащее документам C API, но в отсутствие этой явной документации (поскольку существует для NaN f/e), поведение по умолчанию для синглтона очень актуально.

Charles Duffy 31.03.2023 21:46

@kindall Вот почему я прошу документацию 🙄

Dommondke 31.03.2023 21:47

@user2357112 user2357112 Там прямо сказано, что «достаточно проверки идентичности объекта».

Dommondke 31.03.2023 21:47

Поскольку None является синглтоном (доступ к которому осуществляется только из одной точки памяти), он может быть только одним значением, поэтому == самому себе всегда будет иметь значение True. Надеюсь, это проясняет ситуацию @ user2357112

Caleb Carson 31.03.2023 21:48

Каждый объект сравнивается с самим собой, если иное не определено и не задокументировано; None не задокументирован иначе, а type(None).__eq__ не определен и наследуется от object.

chepner 31.03.2023 21:50

@CalebCarson: у вас могут быть синглтоны, которые не сравниваются сами с собой. Синглтонность здесь не особенная. Поведение == по умолчанию для одиночек — это поведение по умолчанию для объектов в целом, и его можно переопределить, как и для любого другого объекта.

user2357112 31.03.2023 22:22

@Dommondke: В контексте это означает, что вам не нужна проверка типа, чтобы проверить, является ли значение None, как вы бы проверили, было ли значение int или что-то в этом роде, потому что есть только один экземпляр типа None, поэтому сравнения идентичности с None достаточно для проверки типа. На самом деле это ничего не говорит о том, как ведут себя сравнения Python == с None.

user2357112 31.03.2023 22:26

Как указывалось выше, это связано с тем, как None == None оценивается __eq__.

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

Итак, ваш пример похож на высказывание «указывает ли None на тот же объект в памяти, что и None?». Ответ положительный, поэтому __eq__ выполнено (Истина).

Эта ссылка очень подробно объяснит равенство, если вы хотите прочитать об этом.

None == None теоретически может быть определен (и реализован) как False, даже если None является тем же объектом в памяти, что и None.
mkrieger1 31.03.2023 22:07

@ mkrieger1 mkrieger1 вы предлагаете реализовать проверку на равенство способом, отличным от реализации stdlib? В этом случае я согласен, но я не думаю, что это будет в рамках этого вопроса. Python всегда избегал двусмысленности, и оценка None == None (или None is None) всегда будет и должна возвращать True.

Thyll Müller 31.03.2023 22:12
float.__eq__ нервно оглядывается.
chepner 31.03.2023 22:13

@chepner Да ... ну ... я не могу удовлетворить их всех, ха-ха. Мне неловко говорить, что есть необходимые исключения, которые мы должны учитывать, но, к сожалению, здесь это так. Я действительно думаю, что понимание проблемы с представлением чисел с плавающей запятой в двоичном виде является одним из тех, хотя рано или поздно каждый наткнется на эту проблему в своей работе, я думаю.

Thyll Müller 31.03.2023 22:19
float (или, точнее, арифметика с плавающей запятой IEEE 754) имела больше практических интересов, чем математическая чистота :)
chepner 31.03.2023 22:32

Нет явного утверждения, что None == None истинно, но еще в Python 1.5.2 есть два утверждения, которые подразумевают это.

Во-первых, в обсуждении оператора равенства:

Сравнение объектов одного типа зависит от типа:

  • Числа сравниваются арифметически.
  • Строки сравниваются лексикографически с использованием числовых эквивалентов (результат встроенной функции ord()) их персонажи.
  • Кортежи и списки сравниваются лексикографически с использованием сравнения соответствующих элементов.
  • Сопоставления (словари) сравниваются посредством лексикографического сравнения их отсортированных (ключ, значение) списков.
  • Большинство других типов сравниваются неравными, если только они не являются одним и тем же объектом; выбор, считать ли один объект меньшим или большим чем другой производится произвольно, но последовательно в рамках одного выполнение программы.

Однако при каждом использовании Noneотносится к одному и тому же объекту

2.1.7.7 Нулевой объект

Этот объект возвращается функциями, которые явно не возвращают ценить. Он не поддерживает никаких специальных операций. Существует ровно один ноль объект с именем None (встроенное имя).

Пишется как None.

Другие вопросы по теме