Python if x is not None
o if not x is None
?
TLDR: el compilador de bytecode los analiza a ambos, por x is not None
lo que, por razones de legibilidad, úselos if x is not None
.
Legibilidad
Usamos Python porque valoramos cosas como la legibilidad humana, la usabilidad y la corrección de varios paradigmas de programación sobre el rendimiento.
Python optimiza la legibilidad, especialmente en este contexto.
Analizar y compilar el código de bytes
Se not
une más débilmente que is
, por lo que no hay diferencia lógica aquí. Ver la documentación :
Los operadores is
y la is not
prueba de identidad del objeto: x is y
es verdadero si y solo si x e y son el mismo objeto. x is not y
produce el valor de verdad inverso.
El is not
se proporciona específicamente en la gramática de Python como una mejora de legibilidad para el lenguaje:
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
Y, por lo tanto, también es un elemento unitario de la gramática.
Por supuesto, no se analiza igual:
>>> 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())]))"
Pero entonces el compilador de bytes realmente traducirá el not ... is
a 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
Entonces, en aras de la legibilidad y el uso del lenguaje como estaba previsto, utilícelo is not
.
No usarlo no es sabio.
is not
es un operador por derecho propio. Al igual!=
. Si lo prefiere,not x is None
entonces también debería preferirnot a == b
mása != b
.