关于python:Yoda条件与“不是x是无”

Yoda condition with “not x is None”

前一个dev在代码中留下了一个非常奇怪的not x is Noneyoda条件:

1
2
3
4
5
6
>>> x = None
>>> not x is None
False
>>> x = 1
>>> not x is None
True

经过一些测试,我似乎和x is not None的输出相同。

1
2
3
4
5
6
7
8
9
10
>>> x = None
>>> not x is None
False
>>> x is not None
False
>>> x = 1
>>> not x is None
True
>>> x is not None
True

not x is None总是等同于x is not None吗?

要打破这种状况,是not (x is None)还是(not x) is None?还是前者总是等同于后者?


由于isnot具有更高的进位,因此表达式是等价的:

如果是x = Nonex is NoneTrue进行评价,not x is NoneFalse进行评价。如果是x = 1x is NoneFalse进行评价,not x is NoneTrue进行评价。

如果是x = Nonex is not NoneFalse的评价如果是x = 1x is not None评价为True

因此,即使这些操作在语法上不是等价的,结果也是等价的。

这是not x is None的ast:

enter image description here

这是x is not None的ast:

氧化镁

如第二张图所示,内部节点是比较节点,因此在not之前对x is None进行评估。

关于表达式的实际计算,似乎Python为这两个字节码创建了相同的字节码。在这个例子中可以看到:

1
2
3
4
5
6
7
8
9
10
def foo(x):
    x is not None


def bar(x):
    not x is None

import dis
dis.dis(foo)
dis.dis(bar)

两者都会产生:

1
2
3
4
5
6
      0 LOAD_FAST                0 (x)
      3 LOAD_CONST               0 (None)
      6 COMPARE_OP               9 (is not)
      9 POP_TOP            
     10 LOAD_CONST               0 (None)
     13 RETURN_VALUE


在python中,is not是(我认为是唯一的)两个关键字操作符,x is not y完全等同于not x is y。同样的结果也将由id(x) != id(y)返回。最能让读者理解的标准拼写是x is not y