私はif not x is None
のバージョンをもっと明確にすることを常に考えていましたが、Googleの スタイルガイド と PEP-8 は両方ともif x is not None
を使っています。パフォーマンスに多少の違いはありますか(私はそうではないと思います)、そして一方が実際には合わない(もう一方が私のコンベンションにとって明らかに勝者になる)場合はありますか?*
*単にNone
ではなく、任意のシングルトンを参照しています。
... Noneのようなシングルトンを比較します。使用はありません。
これらは同じバイトコードにコンパイルされるので、パフォーマンス上の違いはありません。
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
を書くならば、あいまいさはありません。
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 None
がif not x is None
として正確な結果を持つことを意味します。私は直立します。ありがとうございます。
しかし、私の答えはまだ立っています: 従来のif x is not None
を使用してください。 :]
コードはプログラマにとって最初に、コンパイラまたはインタプリタにとっては理解しやすいように書かれるべきです。 "is not"構文は "not is"よりも英語によく似ています。
答えは人々がそれを作っているより簡単です。
どちらにしても技術的な利点はありません、そして「xはyではありません」が 他の人が使うもの です。 「英語に近い」かどうかは関係ありません。誰もがそれを使用しています。つまり、Pythonのすべてのユーザー - たとえPythonのようには見えない言語の中国語ユーザーであっても - はあまり一般的ではない構文では解析に余分な頭脳サイクルが2回かかるためです。
少なくともこの分野では、異なることだけのために違うことをしないでください。
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
より弱く結合しています ので、ここでは論理的な違いはありません。 ドキュメント :を参照してください。
演算子
is
とis 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 ... 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
を使用してください。
それを使わないためにはではない賢い。
is not
演算子は、スタイル上の理由からis
の結果を否定するよりも優先されます。 "if x is not None:
"は英語のように読みますが、 "if not x is None:
"は演算子の優先順位を理解する必要があり、英語のように読みません。
パフォーマンスに違いがある場合、私のお金はis not
ですが、これはほぼ間違いなくその手法を好むという決定の動機にはなりません。それは明らかに実装依存です。 is
は上書きできないので、とにかく区別を最適化するのは簡単なはずです。
個人的には
if not (x is None):
これは、Pythonシンタックスの専門家でなくても、すべてのプログラマーによってあいまいさなしにすぐに理解されます。
if not x is None
は他のプログラミング言語にもっと似ていますが、if x is not None
は私にとってはっきりしているように聞こえます(そして英語では文法的に正しいです)。
それはそれが私にとってより好みのものであるように思われると言いました。
もっと読みやすいコードを生成するために、演算子の優先順位を処理するコードの書き方を考えるよりも読みやすい形式のx is not y
をお勧めします。