【问题标题】:Python `if x is not None` or `if not x is None`? [closed]Python `if x is not None` 或 `if not x is None`? [关闭]
【发布时间】:2011-02-12 05:56:42
【问题描述】:

我一直认为if not x is None 版本更清晰,但Google 的style guidePEP-8 都使用if x is not None。是否存在任何细微的性能差异(我假设没有),是否有任何情况下一个确实不适合(使另一个明显成为我的大会的赢家)?*

*我指的是任何单身人士,而不仅仅是None

...比较单例 没有。使用是或不是。

【问题讨论】:

  • is not 本身就是一个运算符。喜欢!=。如果您更喜欢not x is None,那么您也应该更喜欢not a == b 而不是a != b
  • @TomaszGandor 我不再对not x is None 有这种看法(这里的答案让我信服)——然而,值得注意的是not a == b 是Python 中的首选样式,与@987654333 相比@.
  • @orokusaki 真的是not a == b 的首选风格吗?我从来没有见过这样做的,而且我看到的每个地方都使用!=
  • @orokusaki 在 Python 中,可读性很重要,因此使用一个运算符 != 而不是两个运算符 not== 是一种首选风格。

标签: python coding-style nonetype boolean-expression pep8


【解决方案1】:

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

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

【讨论】:

  • 除非同一个人类读者认为它是x is (not y)。但我倾向于同意你的其他理由。
  • 此外,“不是”在这种情况下的歧义较少“如果 a 不是无且 b 是无:”与“如果不是 a 是无且 b 是无:”
  • 运算符应该是“aint”
  • 或“除非” (if not x is None -> unless x is None)
  • 我认为恰恰相反。第一次看到x is not y,我以为程序员是在比较x和“not y”。
【解决方案2】:

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 只是最好避免使用。


更多编辑:

我刚刚做了 more 测试,可以确认 bukzor 的评论是正确的。 (至少,我无法证明这一点。)

这意味着if x is not None 的结果与if not x is None 完全相同。我站得更正。谢谢 bukzor。

但是,我的答案仍然成立:使用传统的if x is not None:]

【讨论】:

    【解决方案3】:

    代码应该首先被程序员理解,然后是编译器或解释器。 "is not" 结构比 "not is" 更接近英语。

    【讨论】:

    • "代码应该首先被程序员理解":这是设计COBOL的原则,这是一种非学术语言,受到很多condescension from academics ,有些是合法的,大多数不是。至于原因……“对于计算机科学家来说,同情地写 COBOL 是一种近乎异端的行为。这需要勇气,因为学术同事和数据处理专业人士都可能怀疑我的动机。"
    【解决方案4】:

    Python if x is not Noneif not x is None?

    TLDR:字节码编译器将它们都解析为x is not None - 因此为了便于阅读,请使用if x is not None

    可读性

    我们之所以使用 Python,是因为我们重视各种编程范式的人类可读性、可用性和正确性,而不是性能。

    Python 优化了可读性,尤其是在这种情况下。

    解析和编译字节码

    notbinds more weaklyis,所以这里没有逻辑上的区别。见documentation

    运算符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

    不使用它明智。

    【讨论】:

    • not 的绑定比 is 更弱,所以这里没有逻辑上的区别”——除了 Python 不必强制保持逻辑和代数身份(没有内在原因(1 + 2)*3 评估与1*3 + 2*3 相同)。这里显然 Python 正在欺骗和优化UNARY_NOT
    【解决方案5】:

    答案比人们想象的要简单。

    这两种方式都没有技术优势,而且“x 不是 y”是其他人都使用的,这使其成为明显的赢家。它是否“看起来更像英语”并不重要;每个人都在使用它,这意味着每个 Python 用户——即使是中国用户,他们的语言 Python 看起来一点也不像——都会一眼就能理解,其中稍微不常见的语法将需要几个额外的大脑周期来解析。

    不要仅仅为了与众不同而与众不同,至少在这个领域是这样。

    【讨论】:

      【解决方案6】:

      就个人而言,我使用

      if not (x is None):
      

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

      【讨论】:

      • 我同意一个公平的论点,但我认为遵循惯用风格的论点更有力。
      • +1 对于大多数非 Python 程序员来说,if x is not None 听起来像 if x is (not None),这很可能是一个编码错误。另一方面,对于大多数 python 程序员if not (x is None) 来说,你似乎没有这门语言的经验。
      【解决方案7】:

      出于文体原因,is not 运算符优于否定 is 的结果。 “if x is not None:”读起来像英文,但“if not x is None:”需要理解运算符优先级,读起来不像英文。

      如果存在性能差异,我的钱是is not,但这几乎肯定不是决定更喜欢该技术的动机。它显然是依赖于实现的。由于is 不可覆盖,因此无论如何优化任何区别都应该很容易。

      【讨论】:

        【解决方案8】:

        if not x is None 与其他编程语言更相似,但if x is not None 对我来说肯定听起来更清晰(并且在英语中语法更正确)。

        也就是说,这对我来说似乎更像是一种偏好。

        【讨论】:

          【解决方案9】:

          我更喜欢更易读的形式x is not y 比我想象的如何最终编写运算符的代码处理优先级以生成更具可读性的代码。

          【讨论】:

            猜你喜欢
            • 2016-05-01
            • 2020-12-01
            • 2013-09-06
            • 1970-01-01
            • 1970-01-01
            • 2017-09-12
            • 1970-01-01
            • 2018-09-10
            • 1970-01-01
            相关资源
            最近更新 更多