Подтвердить что ты не робот

Оператор Python в (__contains__) возвращает bool, значение которого не является ни True, ни False

Как и ожидалось, 1 не содержит пустой набор

>>> 1 in ()
False

но возвращаемое значение False не равно False

>>> 1 in () == False
False

Иначе говоря, оператор in возвращает a bool, который не является ни True, ни False:

>>> type(1 in ())
<type 'bool'>
>>> 1 in () == True, 1 in () == False
(False, False)

Однако нормальное поведение возобновляется, если исходное выражение заключено в скобки

>>> (1 in ()) == False
True

или его значение сохраняется в переменной

>>> value = 1 in ()
>>> value == False
True

Это поведение наблюдается как в Python 2, так и в Python 3.

Можете ли вы объяснить, что происходит?

4b9b3361

Ответ 1

Вы работаете в цепочке операторов сравнения; 1 in () == False не означает (1 in ()) == False.

Скорее, сравнения скованы, и выражение действительно означает:

(1 in ()) and (() == False)

Поскольку (1 in ()) уже false, вторая половина закодированного выражения игнорируется вообще (поскольку False and something_else возвращает False независимо от значения something_else).

Смотрите документацию сравнений выражений:

Сравнение может быть скопировано произвольно, например, x < y <= z эквивалентно x < y and y <= z, за исключением того, что y оценивается только один раз (но в обоих случаях z вообще не оценивается, когда x < y быть ложным).

Для записи <, >, ==, >=, <=, !=, is, is not, in и not in - все операторы сравнения (как устаревший <>).

В общем, не сравнивайте с булевыми; просто проверьте само выражение. Если вам нужно протестировать булевский литерал, по крайней мере используйте скобки и оператор is, True и False являются одноточечными, как и None:

>>> (1 in ()) is False
True

Это становится еще более запутанным, когда задействуются целые числа. Тип Python bool является подклассом int 1. Таким образом, False == 0 истинно, как и True == 1. Таким образом, вы можете создавать цепочки операций, которые почти выглядят нормальными:

3 > 1 == True

истинно, потому что 3 > 1 и 1 == True являются истинными. Но выражение:

3 > 2 == True

является ложным, поскольку 2 == True является ложным.

1 bool является подклассом int по историческим причинам; Python не всегда имел тип bool и перегруженные целые числа с булевым значением, как это делает C. При создании bool подкласс сохранял более старый код.