Python `si x n'est pas None` ou `si pas de x est Rien"?
J'ai toujours pensé que la version if not x is None
était plus claire, mais le guide de style de Google et PEP-8 utilisent tous les deux if x is not None
. Y a-t-il une différence de performance mineure (je suppose que non), et y a-t-il un cas où l'un ne correspond vraiment pas (faisant de l'autre un gagnant clair pour ma convention)?*
* je fais référence à n'importe quel singleton, plutôt que simplement None
.
... pour comparer des singletons comme Aucun. L'utilisation est ou n'est pas.
10 réponses
Il N'y a pas de différence de performance, car ils compilent au même bytecode:
Python 2.6.2 (r262:71600, Apr 15 2009, 07:20:39)
>>> import dis
>>> def f(x):
... return x is not None
...
>>> dis.dis(f)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 0 (None)
6 COMPARE_OP 9 (is not)
9 RETURN_VALUE
>>> def g(x):
... return not x is None
...
>>> dis.dis(g)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 0 (None)
6 COMPARE_OP 9 (is not)
9 RETURN_VALUE
Stylistiquement, j'essaie d'éviter de not x is y
. Bien que le compilateur le traite toujours comme not (x is y)
, un lecteur humain peut mal comprendre la construction comme (not x) is y
. Si j'écris x is not y
alors il n'y a pas d'ambiguïté.
Le Guide de style de Google et de Python est la meilleure pratique:
if x is not None:
# Do something about x
L'utilisation de {[3] } peut entraîner des résultats indésirables. Voir ci-dessous:
>>> x = 1
>>> not x
False
>>> x = [1]
>>> not x
False
>>> x = 0
>>> not x
True
>>> x = [0] # You don't want to fall in this one.
>>> not x
False
Vous pourriez être intéressé de voir quels littéraux sont évalués à True
ou False
en Python:
Modifier pour commentaire ci-dessous:
Je viens de faire d'autres tests. not x
est None Ne nie pas x
d'abord et ensuite comparé à None
. En fait, il semble que le L'Opérateur is
a une priorité plus élevée lorsqu'il est utilisé de cette façon:
>>> x
[0]
>>> not x is None
True
>>> not (x is None)
True
>>> (not x) is None
False
Par conséquent, not x is None
est juste, à mon avis honnête, préférable d'éviter.
Plus modifier:
Je viens de faire plus de tests et je peux confirmer que le commentaire de bukzor est correct. (Au moins, je n'ai pas pu le prouver autrement.)
Cela signifie que if x is not None
a le résultat exact comme if not x is None
. Je corrige la position des mains. Merci bukzor.
Cependant, ma réponse tient toujours: utilisez le conventionnel if x is not None
. :]
Le Code doit être écrit pour être compréhensible pour le programmeur d'abord, et le compilateur ou l'interpréteur seconde. La construction "n'est pas" ressemble plus à l'anglais que "n'est pas".
La réponse est plus simple que ce que les gens font.
Il n'y a aucun avantage technique de toute façon, et "x n'est pas y" est ce que tout le monde utilise, ce qui en fait le gagnant clair. Peu importe que cela "ressemble plus à l'anglais" ou non; tout le monde l'utilise, ce qui signifie que chaque utilisateur de Python - même les utilisateurs chinois, dont le langage Python ne ressemble en rien-le comprendra d'un coup d'œil, où la syntaxe un peu moins commune prendra quelques cycles cérébraux supplémentaires pour analyser.
Ne soyez pas différent juste pour être différent, au moins dans ce domaine.
Python
if x is not None
ouif 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, la facilité d'utilisation 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
Le not
lie plus faiblement que is
, donc il n'y a pas de différence logique ici. Voir la documentation :
Les opérateurs
is
etis not
test pour l'identité de l'objet:x is y
est vrai si et seulement si x et y sont le même objet.x is not y
donne le valeur de vérité inverse.
Le is not
est spécifiquement prévu dans la grammaire Python comme une amélioration de la lisibilité pour le langage:
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
Et c'est donc un élément unitaire de la grammaire ainsi.
Bien sûr, il n'est pas analysé de la même manière:
>>> 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 ensuite l'octet compilateur va traduire le 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, par souci de lisibilité et d'utilisation de la langue telle qu'elle était prévue, veuillez utiliser is not
.
Pour ne pas l'utiliser n'est pas sage.
L'opérateur is not
est préféré à la négation du résultat de is
pour des raisons stylistiques. "if x is not None:
"se lit comme l'anglais, mais" if not x is None:
" nécessite la compréhension de la priorité de l'opérateur et ne se lit pas comme l'anglais.
S'il y a une différence de performance, mon argent est sur is not
, mais ce n'est certainement pas la motivation pour la décision de préférer cette technique. Il serait évidemment dépendant de la mise en œuvre. Puisque is
n'est pas substituable, il devrait être facile d'optimiser toute distinction de toute façon.
Personnellement, j'utilise
if not (x is None):
Qui est compris immédiatement sans ambiguïté par tous les programmeurs, même ceux qui ne sont pas experts dans la syntaxe Python.
if not x is None
est plus semblable à d'autres langages de programmation, mais if x is not None
semble certainement plus clair (et plus grammaticalement correcte en anglais) pour moi.
Cela dit, il semble que c'est plus une chose de préférence pour moi.
Je préférerais la forme plus lisible x is not y
que je pense comment écrire éventuellement la priorité de gestion du code des opérateurs afin de produire du code beaucoup plus lisible.