Python的(__contains__)运算符返回一个bool,其值既不是True也不是False

时间:2013-11-03 09:38:26

标签: python boolean membership comparison-operators

正如预期的那样,空元组不包含1

>>> 1 in ()
False

但返回的False值不等于False

>>> 1 in () == False
False

另一种方式是,in运算符返回的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中都观察到了这种行为。

你能解释一下发生了什么吗?

1 个答案:

答案 0 :(得分:45)

您正在进行比较运算符链接; 1 in () == False 表示(1 in ()) == False

相反,比较是链接的,表达式的确意味着:

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

由于(1 in ())已经为假,因此链接表达式的后半部分将被完全忽略(因为False and something_else会返回False,无论something_else的值是什么)。< / p>

请参阅comparisons expressions documentation

  

比较可以任意链接,例如,x < y <= z等同于x < y and y <= z,但y仅评估一次(但在两种情况下z都未评估所有x < y被发现为假的时候。

对于记录,<>==>=<=!=is,{ {1}},is notin都是比较运算符(不推荐使用not in)。

一般来说,不要与布尔相比;只是测试表达本身。如果来测试布尔文字,至少使用括号和<>运算符,isTrue是单例,就像{{1}一样}:

False

当涉及整数时,这会变得更加混乱。 Python None类型是>>> (1 in ()) is False True 1 的子类。因此,bool是正确的,int也是如此。因此,可以想象创建几乎看起来很健全的链式操作:

False == 0

是正确的,因为True == 13 > 1 == True 都是正确的。但表达式是:

3 > 1

为false,因为1 == True为false。

1 3 > 2 == True 是历史原因的2 == True的子类; Python并不总是有一个bool类型和带有布尔意义的重载整数,就像C一样。使int成为子类使旧代码工作。