Python if x is not None
ou if not x is None
?
TLDR: le compilateur de bytecode les analyse tous les deux x is not None
- donc pour des raisons de lisibilité, utilisez if x is not None
.
Lisibilité
Nous utilisons Python parce que nous apprécions des choses comme la lisibilité humaine, l'utilisabilité et l'exactitude de divers paradigmes de programmation par rapport aux performances.
Python optimise la lisibilité, en particulier dans ce contexte.
Analyse et compilation du Bytecode
La not
liaison est plus faible que is
, il n'y a donc pas de différence logique ici. Consultez la documentation :
Les opérateurs is
et le is not
test d'identité d'objet: x is y
est vrai si et seulement si x et y sont le même objet. x is not y
donne la valeur de vérité inverse.
Le is not
est spécifiquement prévu dans la grammaire Python comme une amélioration de la lisibilité du langage:
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
Et c'est donc aussi un élément unitaire de la grammaire.
Bien sûr, ce n'est pas pareil:
>>> 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())]))"
Mais le compilateur octet fait traduire 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
Donc, pour des raisons de lisibilité et d'utilisation de la langue comme prévu, veuillez utiliser is not
.
Ne pas l'utiliser n'est pas sage.
is not
est un opérateur à part entière. Comme!=
. Si vous préféreznot x is None
, votre devrait aussi préférernot a == b
plusa != b
.