Skip to main content
 首页 » 编程设计

python之"not in"和 "is not"都是运算符吗如果是这样,它们与 "not x in.."和 "not x is.."有什么不同吗

2025年05月04日9linjiqin

我一直喜欢这些:

not 'x' in 'abc' 
not 'x' is 'a' 

(当然,假设每个人都知道 in 并且 is out-prioritize not -- 我可能应该使用括号) (英语)语法:

'x' not in 'abc' 
'x' is not 'a' 

但直到我意识到它们在句法上没有意义时才费心去想为什么

'x' == not 'a' 
'x' not == 'a' 

当然都会抛出语法错误。

所以我认为它们都是双词运算符。然而,documentation仅引用 is not 而未提及 not in 作为运算符。我可能误解了语法吗?

如果它们都是运算符,那么它们与非语法运算符有什么不同(甚至是细微差别)?

如果它们相同,那么它们为什么存在?似乎对Zen of Python不敬(..“一个 - 最好只有一个 - 显而易见的方式”..)

如果这已经被讨论到死,我深表歉意,我只是运气不好,用“不是”这样的搜索词找到它。

请您参考如下方法:

使用 dis 很容易检查是否有任何差异模块:

>>> dis.dis(compile('not a in b','','exec')) 
  1           0 LOAD_NAME                0 (a) 
              3 LOAD_NAME                1 (b) 
              6 COMPARE_OP               7 (not in) 
              9 POP_TOP              
             10 LOAD_CONST               0 (None) 
             13 RETURN_VALUE         
>>> dis.dis(compile('a not in b','','exec')) 
  1           0 LOAD_NAME                0 (a) 
              3 LOAD_NAME                1 (b) 
              6 COMPARE_OP               7 (not in) 
              9 POP_TOP              
             10 LOAD_CONST               0 (None) 
             13 RETURN_VALUE         

看到了吗?笨拙的第一种形式(经常让那些不能立即分辨出 not 和 in 运算符的相对优先级的人感到困惑)被编译成与 can't 完全相同的字节码-confuse-anybody 第二个 for,使用单个 not in 运算符。同样:

>>> dis.dis(compile('not a is b','','exec')) 
  1           0 LOAD_NAME                0 (a) 
              3 LOAD_NAME                1 (b) 
              6 COMPARE_OP               9 (is not) 
              9 POP_TOP              
             10 LOAD_CONST               0 (None) 
             13 RETURN_VALUE         
>>> dis.dis(compile('a is not b','','exec')) 
  1           0 LOAD_NAME                0 (a) 
              3 LOAD_NAME                1 (b) 
              6 COMPARE_OP               9 (is not) 
              9 POP_TOP              
             10 LOAD_CONST               0 (None) 
             13 RETURN_VALUE         

这两种形式——愚蠢、令人困惑的第一种,以及优雅的第二种——与完全相同的代码进行比较,并且都使用了 is not 运算符。

当然,没有充分的理由使用会使读者感到困惑的形式(除非您喜欢为那些阅读您的代码的人设置陷阱!-),但在执行语义和速度方面没有任何区别。