web-dev-qa-db-fra.com

Python `si x n'est pas Aucun` ou` si pas x est Aucun`?

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 deux if x is not None. Existe-t-il une différence de performance mineure (je suppose que non) et existe-t-il un cas où l'une ne convient pas (faisant de l'autre un vainqueur évident de mon congrès)? *

* Je parle de n'importe quel singleton, plutôt que de simplement None.

... pour comparer des singletons comme aucun. L'utilisation est ou n'est pas.

651
orokusaki

Il n'y a pas de différence de performances, car ils compilent dans le 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 not x is y. Bien que le compilateur la traite toujours comme not (x is y), un lecteur humain pourrait mal comprendre la construction en tant que (not x) is y. Si j'écris x is not y alors il n'y a pas d'ambiguïté.

903
Daniel Stutzbach

Le guide de style de Google et Python est la meilleure pratique:

if x is not None:
    # Do something about x

L'utilisation de not x 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 quelques tests supplémentaires. not x is None n'annule pas d'abord x puis comparé à None. En fait, il semble que l'opérateur is ait 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, à mon avis honnête, préférable d'éviter.

Plus d'édition:

Je viens de faire plus de tests et peux confirmer que le commentaire de bukzor est correct. (Au moins, je n'ai pas pu le prouver.)

Cela signifie que if x is not None a le résultat exact sous la forme if not x is None. Je me suis trompé. Merci bukzor.

Cependant, ma réponse est toujours valable: Utilisez le conventionnel if x is not None. :]

170
Xavier Ho

Le code doit être écrit pour être compréhensible par le programmeur d’abord, puis par le compilateur ou l’interprète. La construction "is not" ressemble plus à l'anglais que "not is".

122
Mark Ransom

La réponse est plus simple que ce que les gens font.

Il n'y a aucun avantage technique dans les deux cas, et "x n'est pas y" est ce que tout le monde utilise, ce qui en fait clairement le gagnant. Peu importe qu'il "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 à rien - le comprendra d'un coup d'œil, où la syntaxe légèrement moins commune prendra deux cycles cérébraux supplémentaires à analyser .

Ne soyez pas différent juste pour être différent, au moins dans ce domaine.

30
Glenn Maynard

Python if x is not None ou if not x is None?

TLDR: Le compilateur de bytecode les analyse tous les deux comme x is not None - donc pour des raisons de lisibilité, utilisez if x is not None.

Lisibilité

Nous utilisons Python parce que nous attachons une grande importance à la lisibilité humaine, à la facilité d'utilisation et à la correction de divers paradigmes de programmation par rapport aux performances.

Python optimise la lisibilité, en particulier dans ce contexte.

Analyser et compiler le Bytecode

La notse lie plus faiblement que is, il n'y a donc pas de différence logique ici. Voir le documentation :

Les opérateurs is et is not testent 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 la valeur de vérité inverse.

Le is not est spécifiquement prévu dans le Python grammaire comme 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.

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 d’octets traduira le not ... is en 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 du langage tel qu’il était destiné, veuillez utiliser is not.

Ne pas l'utiliser n'est pas sage.

27
Aaron Hall

L'opérateur is not est préférable à 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 de comprendre 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 ce qui motive la décision de préférer cette technique. Cela dépendrait évidemment de la mise en œuvre. Puisque is n'est pas écrasable, il devrait être facile d'optimiser n'importe quelle distinction de toute façon.

10
Mike Graham

Personnellement, j'utilise

if not (x is None):

ce qui est immédiatement compris sans ambiguïté par tous les programmeurs, même ceux qui ne sont pas experts en syntaxe Python.

8
MikeTeX

if not x is None est plus similaire aux autres langages de programmation, mais if x is not None sonne nettement plus clair (et est plus correct grammaticalement en anglais).

Cela dit, il me semble que c'est plus une question de préférence.

2
Davy8

Je préférerais la forme plus lisible x is not y que je penserais comment écrire finalement la priorité de traitement de code des opérateurs afin de produire un code beaucoup plus lisible.

0
stefanogreg