パイソン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
and is not
test:x is y
は、x と y が同じオブジェクトである場合にのみ true になります。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
。
それを使わないのは賢明ではありません。