Python `if x is not None`或`if not x is None`?[关闭]

7gcisfzg  于 2023-05-16  发布在  Python
关注(0)|答案(9)|浏览(126)

已关闭,此问题需要details or clarity。目前不接受答复。
**想改善这个问题吗?**通过editing this post添加详细信息并澄清问题。

两年前关闭。
Improve this question
我一直认为if not x is None版本更清晰,但Google的风格指南和PEP-8都使用if x is not None。是否有任何微小的性能差异(我假设没有),是否有任何情况下,其中一个真的不适合(使另一个明显的赢家,我的公约)?*

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

……比较像None这样的单身汉。使用是或不是。

5lhxktic

5lhxktic1#

没有性能差异,因为它们编译为相同的字节码:

>>> 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,那么就没有歧义。

xkrw2x1b

xkrw2x1b2#

Google和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 None的精确结果为if not x is None。我承认错误。谢谢bukzor。
然而,我的答案仍然成立:使用常规if x is not None:]

uemypmqf

uemypmqf3#

代码应该首先编写成程序员可以理解的,其次才是编译器或解释器。“is not”结构比“not is”更接近英语。

j2datikz

j2datikz4#

Python if x is not None还是if not x is None

TLDR:字节码编译器将它们都解析为x is not None--所以为了可读性,使用if x is not None

可读性

我们使用Python是因为我们更看重人类的可读性、可用性和各种编程范式的正确性,而不是性能。
Python优化了可读性,特别是在这种情况下。

解析编译字节码

not的绑定比is弱,所以这里没有逻辑上的区别。请参阅文档:
运算符isis not测试对象标识:x is y为真,当且仅当x和y是同一个对象。x is not y产生逆真值。
is not是专门在Python grammar中提供的,作为该语言的可读性改进:

comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'

所以它也是语法的一个单一元素。
当然,它的解析方式并不相同:

>>> import ast
>>> ast.dump(ast.parse('x is not None').body[0].value)
"Compare(left=Name(id='x', ctx=Load()), ops=[IsNot()], comparators=[Name(id='None', ctx=Load())])"
>>> ast.dump(ast.parse('not x is None').body[0].value)
"UnaryOp(op=Not(), operand=Compare(left=Name(id='x', ctx=Load()), ops=[Is()], comparators=[Name(id='None', ctx=Load())]))"

但是字节编译器实际上会将not ... is转换为is not

>>> import dis
>>> dis.dis(lambda x, y: x is not y)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE
>>> dis.dis(lambda x, y: not x is y)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE

因此,为了可读性和使用语言的目的,请使用is not
不使用它是不明智的。

oogrdqng

oogrdqng5#

答案比人们想的要简单。
无论哪种方式,都没有技术优势,而且“x不是y”是其他人都在使用的东西,这使它成为明显的赢家。它“看起来更像英语”与否并不重要;每个人都使用它,这意味着每个Python用户-甚至是中国用户,他们的语言Python看起来一点也不像-都会一眼就理解它,而稍微不太常见的语法将需要几个额外的大脑周期来解析。
不要为了与众不同而与众不同,至少在这个领域。

4uqofj5v

4uqofj5v6#

就我个人而言,我用

if not (x is None):

每个程序员都能立即理解它,即使是那些不精通Python语法的程序员。

iswrvxsc

iswrvxsc7#

出于风格上的原因,is not运算符优于对is的结果求反。“if x is not None:”读起来像英语,但“if not x is None:”需要理解运算符优先级,读起来不像英语。
如果有性能差异,我认为是is not,但这几乎肯定不是决定更喜欢这种技术的动机。这显然取决于实现。由于is是不可重写的,因此无论如何都应该很容易优化出任何区别。

szqfcxe2

szqfcxe28#

if not x is None更类似于其他编程语言,但if x is not None听起来更清晰(在英语中语法更正确)。
也就是说,这对我来说更像是一种偏好。

r8uurelv

r8uurelv9#

我更喜欢可读的形式x is not y,而不是考虑如何最终编写处理运算符优先级的代码,以产生更可读的代码。

相关问题