Ответ 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
подкласс сохранял более старый код.