我一直喜欢这些:
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 运算符。
当然,没有充分的理由使用会使读者感到困惑的形式(除非您喜欢为那些阅读您的代码的人设置陷阱!-),但在执行语义和速度方面没有任何区别。
