Python中意外的多操作符行为

时间:2019-02-14 02:10:42

标签: python python-3.x operators bytecode

这个问题是出于纯粹出于Python的好奇心/学术兴趣提出的。

假设我有以下代码段:

>>> 1 in [1,2] == False
False

由于in的优先级高于==,而[1,2]中的1的求值结果为TrueTrue != 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?幕后究竟发生了什么事?

0 个答案:

没有答案