Python中'is'运算符与'in'结合使用时的奇怪行为

6
Python如何解释 "'a' in 'abc' is True"?我尝试评估以下两个表达式:
>>> 'a' in 'abc' is True:
False
>>> ('a' in 'abc') is True:
True

我知道通常不应该使用 "is" 关键字来与 True 进行比较,这只是一个例子。


3
你正在将运算符链接起来。 - Martijn Pieters
1个回答

10

有趣的问题!

以下是 'a' in 'abc' is True 的字节码:

>>> import dis
>>> dis.disassemble((lambda: 'a' in 'abc' is True).func_code)
2           0 LOAD_CONST               1 ('a')   # stack: 'a'
            3 LOAD_CONST               2 ('abc') # stack: 'a' 'abc'
            6 DUP_TOP                            # stack: 'a' 'abc' 'abc'
            7 ROT_THREE                          # stack: 'abc' 'a' 'abc'
            8 COMPARE_OP               6 (in)    # stack: 'abc' True
           11 JUMP_IF_FALSE_OR_POP    21         # stack: 'abc'
           14 LOAD_GLOBAL              0 (True)  # stack: 'abc' True
           17 COMPARE_OP               8 (is)    # stack: False
           20 RETURN_VALUE        
      >>   21 ROT_TWO
           22 POP_TOP
           23 RETURN_VALUE                      

('a' in 'abc') is True 相比较:

>>> import dis
>>> dis.disassemble((lambda: ('a' in 'abc') is True).func_code)
1           0 LOAD_CONST               1 ('a')   # stack: 'a'
            3 LOAD_CONST               2 ('abc') # stack: 'a' 'abc'
            6 COMPARE_OP               6 (in)    # stack: True
            9 LOAD_GLOBAL              0 (True)
           12 COMPARE_OP               8 (is)
           15 RETURN_VALUE        

因此,似乎表达式'a' in 'abc' is True的评估结果大致如下:

>>> 'a' in 'abc' and 'abc' is True

看起来这是运算符链的结果:https://dev59.com/OWIj5IYBdhLWcg3w8JNZ#19751586 —— 同样的魔法也使得1 < 5 < 10能够正常工作。

非常有趣!

(注:此操作在CPython 2.7.2上完成)


抱歉,见编辑说明。 - David Wolever
请查看马特金提供的链接。 - alko
太好了。很棒,我无法从汇编语言输出中推断出来。谢谢。 - karthikr
你没有完全理解它。将'a' in 'abc' is True转换为'abc' in 'a' and 'abc' is True,使用*and*而不是or。只有当两个比较都为真时,整个表达式才为真。 - Martijn Pieters
唉!这就是我匆忙回答的后果。谢谢。 - David Wolever

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接