这个问题是出于纯粹出于Python的好奇心/学术兴趣提出的。
假设我有以下代码段:
>>> 1 in [1,2] == False
False
由于in
的优先级高于==
,而[1,2]中的1的求值结果为True
和True != False
。
但是看到:
>>> 10 in [1,2] == False
False
这令人惊讶,因为[1,2]中的10等于False
,而False == False
等于True
。
我可以证明这不是因为==
首先被评估,因为它甚至不会运行:
>>> 10 in ([1,2] == False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: argument of type 'bool' is not iterable
如果in
语句首先通过括号运行,则 将返回True
:
>>> (10 in [1,2]) == False
True
# Note: All of above work in the same way if numbers and list are substituted by variables.
我去dis
并发现了一个有趣的警告:
def func(): return (x in y == False)
dis.dis(func)
0 LOAD_FAST 0 (x)
2 LOAD_FAST 1 (y)
4 DUP_TOP
6 ROT_THREE
8 COMPARE_OP 6 (in)
10 JUMP_IF_FALSE_OR_POP 18
12 LOAD_CONST 1 (False)
14 COMPARE_OP 2 (==)
16 RETURN_VALUE
>> 18 ROT_TWO
20 POP_TOP
22 RETURN_VALUE
如果为假,JUMP_IF_FALSE_OR_POP
字节码将完全跳过==
部分(到18)。但是,在本质上相同的字节码上执行x in y == True
也总是评估为True。而且,在in
或==
操作中都看不到该字节码,必须生成一些东西。
那么这里到底是怎么回事?为什么所有以x in y == (bool)
格式表示的内容始终求值为False
?幕后究竟发生了什么事?