Python `if x 不是 None` 和 `if not x 是 None`?

1019 投票
9 回答
1431084 浏览
提问于 2025-04-15 22:00

我一直觉得用 if not x is None 这种写法更清晰,但谷歌的风格指南PEP-8 都推荐用 if x is not None。这两种写法在性能上有没有什么小差别(我猜应该没有),有没有什么情况下其中一种写法明显不合适,导致另一种写法更好用呢?*

*我指的是任何单例,而不仅仅是 None

...比较像 None 这样的单例时,使用 is 或 is not。

9 个回答

144

代码应该首先写得让程序员能理解,其次才是让编译器或解释器能理解。这里的“is not”这个写法更像英语,而不是“not is”。

424

谷歌和Python的风格指南都是最佳实践:

if x is not None:
    # Do something about x

使用 not x 可能会导致一些意想不到的结果。

看看下面的例子:

>>> x = 1
>>> not x
False
>>> x = [1]
>>> not x
False
>>> x = 0
>>> not x
True
>>> x = [0]         # You don't want to fall in this one.
>>> not x
False

你可能会想知道在Python中哪些字面量会被判断为 TrueFalse


下面是对评论的补充:

我刚刚做了一些额外的测试。 not x is None 并不是先对 x 取反,然后再和 None 比较。实际上,似乎在这种用法中,is 操作符的优先级更高:

>>> x
[0]
>>> not x is None
True
>>> not (x is None)
True
>>> (not x) is None
False

因此,not x is None 在我看来,最好还是避免使用。


更多补充:

我刚刚又做了更多测试,可以确认bukzor的评论是正确的。(至少,我没有找到反例。)

这意味着 if x is not Noneif not x is None 的结果是完全一样的。我承认错误。谢谢你,bukzor。

不过,我的观点依然成立:还是使用常规的 if x is not None:]

1295

它们在性能上没有区别,因为编译后生成的字节码是一样的:

>>> import dis
>>> dis.dis("not x is None")
  1           0 LOAD_NAME                0 (x)
              2 LOAD_CONST               0 (None)
              4 COMPARE_OP               9 (is not)
              6 RETURN_VALUE
>>> dis.dis("x is not None")
  1           0 LOAD_NAME                0 (x)
              2 LOAD_CONST               0 (None)
              4 COMPARE_OP               9 (is not)
              6 RETURN_VALUE

从风格上讲,我尽量避免使用 not x is y 这种写法,因为人看了可能会误解成 (not x) is y。如果我写 x is not y,那么就没有歧义了。

撰写回答