Question Pas de test en Python [dupliquer]


Cette question a déjà une réponse ici:

Hors de ces tests, aucun.

if val != None:

if not (val is None):

if val is not None:

Lequel est préférable, et pourquoi?


479
2017-10-19 03:20


origine


Réponses:


if val is not None:
    # ...

est l'idiome de Pythonic pour tester qu'une variable n'est pas définie pour None. Cet idiome a des utilisations particulières dans le cas de déclarer des fonctions de mot clé avec des paramètres par défaut. is teste l'identité en Python. Parce qu'il y a une et une seule instance de None présent dans un script / programme Python en cours d'exécution, is est le test optimal pour cela. Comme Johnsyweb souligne, cela est discuté dans PEP 8 sous "Recommandations de programmation".

Quant à savoir pourquoi cela est préférable à

if not (val is None):
    # ...

c'est simplement une partie de la Zen de Python: "La lisibilité compte" Bon Python est souvent proche du bien pseudocode.


688
2017-10-19 03:24



De, Recommandations de programmation, PEP 8:

Les comparaisons avec des singletons comme None doivent toujours être faites avec   «is» ou «is not», jamais les opérateurs d'égalité.

Aussi, méfiez-vous d'écrire "si x" quand vous voulez vraiment dire "si x n'est pas None"   -- par exemple. lors du test si une variable ou un argument par défaut   Aucune n'a été définie pour une autre valeur. L'autre valeur peut avoir un type   (comme un conteneur) qui pourrait être faux dans un contexte booléen!

PEP 8 est une lecture essentielle pour tout programmeur Python.


79
2017-10-19 03:35



L'un ou l'autre des deux derniers, puisque val pourrait potentiellement être d'un type qui définit __eq__() pour retourner vrai quand il est passé None.


19
2017-10-19 03:23



Le meilleur choix avec ces types de questions est de voir exactement ce que fait Python. le dis le module est incroyablement informatif:

>>> def f(val):
...   if val != None:
...     return True
...   return False
...
>>> def g(val):
...   if not (val is None):
...     return True
...   return False
...
>>> def h(val):
...   if val is not None:
...     return True
...   return False
...
>>> import dis
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (val)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               3 (!=)
              9 POP_JUMP_IF_FALSE       16

  3          12 LOAD_GLOBAL              1 (True)
             15 RETURN_VALUE

  4     >>   16 LOAD_GLOBAL              2 (False)
             19 RETURN_VALUE
>>> dis.dis(g)
  2           0 LOAD_FAST                0 (val)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 POP_JUMP_IF_FALSE       16

  3          12 LOAD_GLOBAL              1 (True)
             15 RETURN_VALUE

  4     >>   16 LOAD_GLOBAL              2 (False)
             19 RETURN_VALUE
>>> dis.dis(h)
  2           0 LOAD_FAST                0 (val)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 POP_JUMP_IF_FALSE       16

  3          12 LOAD_GLOBAL              1 (True)
             15 RETURN_VALUE

  4     >>   16 LOAD_GLOBAL              2 (False)
             19 RETURN_VALUE

Notez que les deux derniers cas se réduisent à la même séquence d'opérations (lectures en python not (val is None) et utilise le is not opérateur). Le premier utilise le != opérateur en comparant avec Aucun.

Comme indiqué par d'autres réponses, en utilisant != en comparant avec None est une mauvaise idée


13
2017-10-20 19:44