为什么`True == False是False`评估为False?

ray*_*ylu 32 python

我在一个表达式上得到一些相当意想不到的行为,==但不能用于is:

>>> (True == False) is False
True
>>> True == (False is False)
True
>>> True == False is False
False
>>> id(True)
8978640
>>> id(False)
8978192
>>> id(True == False)
8978192
>>> id(False is False)
8978640
Run Code Online (Sandbox Code Playgroud)

jor*_*eca 40

因为实际上这是一个链式比较,所以

True == False is False
Run Code Online (Sandbox Code Playgroud)

相当于

(True == False) and (False is False)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,这可能会令人惊讶,但是让你的写作1 <= x < 4不同于其他语言,如C.

  • @zzzzBov 我完全同意,这就是我*确实*包装它们的原因;) (7认同)
  • 这就是为什么我倾向于将复杂的逻辑比较包含在parens中,我根本无法记住我使用的所有语言的语法,并且不值得将它们关闭并具有意外行为的风险. (5认同)

Ash*_*ary 12

来自文档:

x <y <= z等于x <y且y <= z,除了y仅被评估一次(但在两种情况下,当x <y被发现为假时,根本不评估z).

在你的情况下True == False is False相当于True == False and False is False第一个条件是False短路和返回False.

>>> dis.dis(lambda : True == False is False)
  1           0 LOAD_GLOBAL              0 (True)
              3 LOAD_GLOBAL              1 (False)
              6 DUP_TOP             
              7 ROT_THREE           
              8 COMPARE_OP               2 (==)
             11 JUMP_IF_FALSE_OR_POP    21          <---------this step
             14 LOAD_GLOBAL              1 (False)
             17 COMPARE_OP               8 (is)
             20 RETURN_VALUE        
        >>   21 ROT_TWO             
             22 POP_TOP             
             23 RETURN_VALUE  
Run Code Online (Sandbox Code Playgroud)

  • 感谢dis.dis().我学到了很有用的东西.:) (3认同)
  • 我没有反对,但在我看来,语言规则的描述足以理解发生了什么。反汇编似乎没有增加太多(除了关注特定于实现的细节)。 (2认同)

Syl*_*inD 9

文档

5.9. 比较

与 C 不同,Python 中的所有比较操作都具有相同的优先级,低于任何算术、移位或按位运算的优先级。同样与 C 不同的是,像 a < b < c 这样的表达式具有数学中的常规解释:

comparison    ::=  or_expr ( comp_operator or_expr )*
comp_operator ::=  "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
                   | "is" ["not"] | ["not"] "in"
Run Code Online (Sandbox Code Playgroud)