Y a-t-il une différence entre « foo is None » et « foo == None » ?

StackOverflow https://stackoverflow.com/questions/26595

  •  09-06-2019
  •  | 
  •  

Question

Y a-t-il une différence entre :

if foo is None: pass

et

if foo == None: pass

La convention que j'ai vue dans la plupart du code Python (et dans le code que j'écris moi-même) est la première, mais je suis récemment tombé sur du code qui utilise la seconde.Aucun n'est une instance (et la seule instance, IIRC) de NoneType, donc cela ne devrait pas avoir d'importance, n'est-ce pas ?Y a-t-il des circonstances dans lesquelles cela pourrait se produire ?

Était-ce utile?

La solution

is revient toujours True s'il compare la même instance d'objet

Alors que == est finalement déterminé par le __eq__() méthode

c'est à dire.


>>> class Foo(object):
       def __eq__(self, other):
           return True

>>> f = Foo()
>>> f == None
True
>>> f is None
False

Autres conseils

Vous voudrez peut-être lire ceci identité et équivalence de l'objet.

L'instruction 'is' est utilisée pour l'identité des objets, elle vérifie si les objets font référence à la même instance (même adresse en mémoire).

Et l'instruction '==' fait référence à l'égalité (même valeur).

Un mot d'avertissement:

if foo:
  # do something

Est pas exactement la même que:

if x is not None:
  # do something

Le premier est un test de valeur booléenne et peut être évalué comme faux dans différents contextes.Il y a un certain nombre de choses qui représentent faux dans les tests de valeurs booléennes, par exemple des conteneurs vides, des valeurs booléennes.Aucun n'est également évalué comme faux dans cette situation, mais d'autres choses le sont également.

(ob1 is ob2) égal à (id(ob1) == id(ob2))

La raison foo is None est la méthode préférée, c'est que vous manipulez peut-être un objet qui définit son propre __eq__, et cela définit l'objet comme étant égal à None.Alors, utilisez toujours foo is None si tu as besoin de voir si c'est effectivement le cas None.

Il n’y a pas de différence car les objets identiques seront bien sûr égaux.Cependant, PPE 8 indique clairement que vous devez utiliser is:

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

is tests d'identité, pas égalité.Pour votre déclaration foo is none, Python compare simplement l'adresse mémoire des objets.Cela signifie que vous posez la question « Ai-je deux noms pour le même objet ? »

== d'autre part, des tests d'égalité déterminés par le __eq__() méthode.Il ne se soucie pas de l'identité.

In [102]: x, y, z = 2, 2, 2.0

In [103]: id(x), id(y), id(z)
Out[103]: (38641984, 38641984, 48420880)

In [104]: x is y
Out[104]: True

In [105]: x == y
Out[105]: True

In [106]: x is z
Out[106]: False

In [107]: x == z
Out[107]: True

None est un opérateur singleton.Donc None is None est toujours vrai.

In [101]: None is None
Out[101]: True

Pour None, il ne devrait pas y avoir de différence entre l'égalité (==) et l'identité (est).Le NoneType renvoie probablement l'identité pour l'égalité.Puisque None est la seule instance que vous pouvez créer de NoneType (je pense que c'est vrai), les deux opérations sont les mêmes.Dans le cas d’autres types, ce n’est pas toujours le cas.Par exemple:

list1 = [1, 2, 3]
list2 = [1, 2, 3]
if list1==list2: print "Equal"
if list1 is list2: print "Same"

Cela afficherait "Égal" puisque les listes ont une opération de comparaison qui n'est pas le retour d'identité par défaut.

@Jason:

Je recommande d'utiliser quelque chose de plus dans le sens de

if foo:
    #foo isn't None
else:
    #foo is None

Je n'aime pas utiliser "if foo:" à moins que foo ne représente vraiment une valeur booléenne (c'est-à-dire0 ou 1).Si foo est une chaîne, un objet ou autre chose, "if foo:" peut fonctionner, mais cela me ressemble à un raccourci paresseux.Si vous vérifiez si x est Aucun, dites "si x est Aucun :".

Quelques détails supplémentaires :

  1. Le is la clause vérifie en fait si les deux objectLes s sont au même emplacement de mémoire ou non.c'est-à-dire s'ils pointent tous les deux vers le même emplacement de mémoire et ont le même id.

  2. En conséquence de 1, is garantit si, ou non, les deux lexiquement représentés objects ont des attributs identiques (attributs-d-attributs...) ou non

  3. Instanciation de types primitifs comme bool, int, string(sauf quelques exceptions), NoneType ayant la même valeur sera toujours dans le même emplacement mémoire.

Par exemple.

>>> int(1) is int(1)
True
>>> str("abcd") is str("abcd")
True
>>> bool(1) is bool(2)
True
>>> bool(0) is bool(0)
True
>>> bool(0)
False
>>> bool(1)
True

Et depuis NoneType ne peut avoir qu'une seule instance de lui-même dans la table "de recherche" de python, donc le premier et le second sont davantage un style de programmation du développeur qui a écrit le code (peut-être par souci de cohérence) plutôt que d'avoir une raison logique subtile d'en choisir une sur l'autre.

La conclusion de John Machin selon laquelle None est un singleton est une conclusion renforcée par ce code.

>>> x = None
>>> y = None
>>> x == y
True
>>> x is y
True
>>> 

Depuis None est un singleton, x == None et x is None aurait le même résultat.Cependant, à mon avis esthétique, x == None est le meilleur.

a is b # returns true if they a and b are true alias
a == b # returns true if they are true alias or they have values that are deemed equivalence 


a = [1,3,4]
b = a[:] #creating copy of list
a is b # if gives false
False
a == b # gives true
True
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top