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.

533
demandé sur orokusaki 2010-04-26 07:10:30

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é.

800
répondu Daniel Stutzbach 2010-04-26 03:55:04

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. :]

123
répondu Xavier Ho 2016-06-30 16:26:07

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".

113
répondu Mark Ransom 2010-04-26 03:15:55

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.

26
répondu Glenn Maynard 2010-04-26 07:18:03

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, 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 et is 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.

15
répondu Aaron Hall 2017-06-13 16:11:26

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.

8
répondu Mike Graham 2010-04-26 04:32:34

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.

5
répondu MikeTeX 2016-06-26 16:14:23

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.

1
répondu Davy8 2010-04-26 03:14:29

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.

0
répondu stefanogreg 2015-09-24 07:19:34

Essayez ceci:

    if x != None:
       # do stuff with x
-3
répondu tylerswright 2015-07-16 15:06:19