web-dev-qa-db-ja.com

Pythonは `xがなしではない場合 'ですか、それとも` xがなしではない場合'ですか?

私はif not x is Noneのバージョンをもっと明確にすることを常に考えていましたが、Googleの スタイルガイドPEP-8 は両方ともif x is not Noneを使っています。パフォーマンスに多少の違いはありますか(私はそうではないと思います)、そして一方が実際には合わない(もう一方が私のコンベンションにとって明らかに勝者になる)場合はありますか?*

*単にNoneではなく、任意のシングルトンを参照しています。

... Noneのようなシングルトンを比較します。使用はありません。

617
orokusaki

これらは同じバイトコードにコンパイルされるので、パフォーマンス上の違いはありません。

Python 2.6.2 (r262:71600, Apr 15 2009, 07:20:39)
>>> import dis
>>> def f(x):
...    return x is not None
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE
>>> def g(x):
...   return not x is None
...
>>> dis.dis(g)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE

文体的に、私はnot x is yを避けようとします。コンパイラは常にそれをnot (x is y)として扱いますが、人間の読者は構文を(not x) is yとして誤解するかもしれません。私がx is not yを書くならば、あいまいさはありません。

869

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では、どのリテラルがTrueまたはFalseに評価されるのかを知りたい場合があります。

以下のコメントを編集してください:

もう少しテストをしました。 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 Noneif not x is Noneとして正確な結果を持つことを意味します。私は直立します。ありがとうございます。

しかし、私の答えはまだ立っています: 従来のif x is not Noneを使用してください。 :]

152
Xavier Ho

コードはプログラマにとって最初に、コンパイラまたはインタプリタにとっては理解しやすいように書かれるべきです。 "is not"構文は "not is"よりも英語によく似ています。

119
Mark Ransom

答えは人々がそれを作っているより簡単です。

どちらにしても技術的な利点はありません、そして「xはyではありません」が 他の人が使うもの です。 「英語に近い」かどうかは関係ありません。誰もがそれを使用しています。つまり、Pythonのすべてのユーザー - たとえPythonのようには見えない言語の中国語ユーザーであっても - はあまり一般的ではない構文では解析に余分な頭脳サイクルが2回かかるためです。

少なくともこの分野では、異なることだけのために違うことをしないでください。

29
Glenn Maynard

Pythonのif x is not Noneまたはif not x is None

TLDR:バイトコードコンパイラは両方をx is not Noneにパースします - 読みやすくするためにif x is not Noneを使います。

読みやすさ

私たちは人間の読みやすさ、使いやすさ、そしてパフォーマンスに対するプログラミングのさまざまなパラダイムの正しさのようなものを重視するので、私たちはPythonを使います。

Pythonは、特にこの文脈において読みやすさを最適化します。

バイトコードの解析とコンパイル

notisより弱く結合しています ので、ここでは論理的な違いはありません。 ドキュメント :を参照してください。

演算子isis notは、オブジェクトの同一性をテストします。x is yは、xとyが同じオブジェクトである場合に限り真となります。 x is not yは、逆の真理値を返します。

is notは、Python 文法 で言語の読みやすさの向上のために特別に提供されています。

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 ... isis 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を使用してください。

それを使わないためにはではない賢い。

23
Aaron Hall

is not演算子は、スタイル上の理由からisの結果を否定するよりも優先されます。 "if x is not None:"は英語のように読みますが、 "if not x is None:"は演算子の優先順位を理解する必要があり、英語のように読みません。

パフォーマンスに違いがある場合、私のお金はis notですが、これはほぼ間違いなくその手法を好むという決定の動機にはなりません。それは明らかに実装依存です。 isは上書きできないので、とにかく区別を最適化するのは簡単なはずです。

9
Mike Graham

個人的には

if not (x is None):

これは、Pythonシンタックスの専門家でなくても、すべてのプログラマーによってあいまいさなしにすぐに理解されます。

6
MikeTeX

if not x is Noneは他のプログラミング言語にもっと似ていますが、if x is not Noneは私にとってはっきりしているように聞こえます(そして英語では文法的に正しいです)。

それはそれが私にとってより好みのものであるように思われると言いました。

1
Davy8

もっと読みやすいコードを生成するために、演算子の優先順位を処理するコードの書き方を考えるよりも読みやすい形式のx is not yをお勧めします。

0
stefanogreg