Python if x is not None
o if not x is None
?
TLDR: il compilatore bytecode li analizza entrambi x is not None
, quindi, per motivi di leggibilità, utilizzare if x is not None
.
leggibilità
Usiamo Python perché apprezziamo cose come la leggibilità umana, l'usabilità e la correttezza di vari paradigmi di programmazione rispetto alle prestazioni.
Python ottimizza per la leggibilità, soprattutto in questo contesto.
Analisi e compilazione del Bytecode
I not
vincoli sono più deboli di is
, quindi non c'è alcuna differenza logica qui. Vedi la documentazione :
Operatori is
e is not
test per l'identità dell'oggetto: x is y
è vero se e solo se xey sono lo stesso oggetto. x is not y
produce il valore della verità inversa.
Questo is not
è specificamente previsto nella grammatica di Python come miglioramento della leggibilità per la lingua:
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
E quindi è anche un elemento unitario della grammatica.
Certo, non viene analizzato lo stesso:
>>> 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())]))"
Ma poi il compilatore di byte tradurrà effettivamente not ... is
in 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
Quindi, per motivi di leggibilità e utilizzo della lingua come previsto, si prega di utilizzare is not
.
Non usarlo non è saggio.
is not
è un operatore a sé stante. Come!=
. Se si preferiscenot x is None
allora la vostra dovrebbe anche preferirenot a == b
sopraa != b
.