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オブジェクトIDのテスト:x is yxと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。
使用しないのは賢明ではありません。
is notそれ自体が演算子です。のように!=。ご希望の場合はnot x is None、あなたのも好むはずですnot a == b以上a != b。