Comparaison de Python None: dois-je utiliser «is» ou ==?

213

Mon éditeur m'avertit lorsque je compare my_var == None, mais aucun avertissement lorsque j'utilise my_var is None.

J'ai fait un test dans le shell Python et j'ai déterminé que les deux sont une syntaxe valide, mais mon éditeur semble dire que my_var is Nonec'est préférable.

Est-ce le cas, et si oui, pourquoi?

Clay Wardell
la source
7
PEP 8 dit quelque part que vous devriez comparer aux singletons en utilisant is- python.org/dev/peps/pep-0008/#programming-recommendations
Volatilité
2
Cette affiche parle de Python 3, et ma question concerne Python 2.x. Je ne suis pas sûr que ce soit une différence suffisamment grande pour justifier que les deux restent, mais j'ai modifié la question pour l'inclure juste au cas où.
Clay Wardell du
2
Je ne pense pas que cette question soit vraiment un doublon. L'autre portait sur == vs est en général, celui-ci est sur None en particulier.
IJ Kennedy

Réponses:

254

Résumé:

À utiliser islorsque vous souhaitez vérifier l' identité d' un objet (par exemple, vérifier si varc'est le cas None). À utiliser ==lorsque vous souhaitez vérifier l' égalité (par exemple Isvar égal à 3?).

Explication:

Vous pouvez avoir des classes personnalisées où my_var == None reviendrontTrue

par exemple:

class Negator(object):
    def __eq__(self,other):
        return not other

thing = Negator()
print thing == None    #True
print thing is None    #False

isvérifie l' identité de l' objet . Il n'y a qu'un seul objet None, donc quand vous le faites my_var is None, vous vérifiez s'il s'agit bien du même objet (pas seulement des objets équivalents )

En d'autres termes, ==est une vérification d'équivalence (qui est définie d'objet à objet) tandis que isvérifie l'identité d'objet:

lst = [1,2,3]
lst == lst[:]  # This is True since the lists are "equivalent"
lst is lst[:]  # This is False since they're actually different objects
mgilson
la source
22
Quand is Nonediffère- == Nonet-il?
Blender
11
@Blender Dans le cas mentionné. __eq__peut être défini de quelque façon que ce soit, mais le comportement de isne peut pas être modifié si facilement.
Lev Levitsky
5
@LevLevitsky: L'un des exemples d'utilisation de Mython était "l'extension des protocoles afin que tout opérateur puisse être surchargé, même is". Après un commentaire sur les listes, il a changé cela en "… même is(mais seulement si vous êtes fou)."
abarnert
1
+1, mais ce serait encore mieux si cette réponse incluait la référence PEP 8 que les autres font (ainsi que d'expliquer pourquoi la décision derrière PEP 8 est logique, ce qu'elle fait déjà).
abarnert
3
@abarnert - Je ne savais même pas que PEP 8 avait fait une recommandation ici. Le fait est que ce sont des opérateurs différents qui font des choses différentes. Il pourrait y avoir des cas où en object == Nonefait c'est le bon idiome (bien que je ne puisse pas penser à n'importe quoi du haut de ma tête). Vous avez juste besoin de savoir ce que vous faites.
mgilson
127

isest généralement préféré lors de la comparaison d'objets arbitraires à des singletons comme Noneparce qu'il est plus rapide et plus prévisible. iscompare toujours par identité d'objet, tandis que ce qui ==va dépendre du type exact des opérandes et même de leur ordre.

Cette recommandation est soutenue par le PEP 8 , qui déclare explicitement que "les comparaisons avec des singletons comme None devraient toujours être faites avec isou is not, jamais avec les opérateurs d'égalité".

user4815162342
la source
6
Merci d'avoir posté ceci; la réponse acceptée soulève quelques points intéressants, mais la vôtre répond beaucoup plus directement à la question.
Luke Davis
Il semble étrange de s'appuyer sur ce qui est essentiellement un détail d'implémentation. Pourquoi devrais-je me soucier du nombre d'instances de NoneType?
BallpointBen
@BallpointBen Parce que ce n'est pas un détail d'implémentation - il n'y a qu'un seul Noneobjet sous la constante globale None. Si quelque chose, NoneTypec'est un détail d'implémentation parce que le Nonesingleton doit avoir un certain type. (Le fait que vous ne puissiez pas créer d'instances de ce type est une bonne indication que sa seule instance est destinée à être un singleton.)
user4815162342
@BallpointBen Je pense que le point clé est que Python possède un fort concept d'identité d'objet. Si vous voulez vérifier si un objet se compare égal à None, par tous les moyens utiliser obj == None. Si vous souhaitez vérifier si un objet l' est None , utilisez obj is None. Le point de la recommandation PEP 8 (et de cette réponse) est que la plupart des gens veulent ce dernier quand ils veulent vérifier Aucun, et il se trouve également que c'est plus rapide et plus clair.
user4815162342
Noneest également différent des objets mis en cache comme 0et d'autres petits entiers, où la mise en cache est vraiment un détail d'implémentation. La différence est qu'un entier a une valeur intrinsèque qui donne ses propriétés et qu'il peut être calculé. D'un autre côté, Nonen'a aucun état, c'est seulement son identité qui compte et la rend spéciale.
user4815162342
11

PEP 8 définit qu'il est préférable d'utiliser l' isopérateur lors de la comparaison de singletons.

Thorsten Kranz
la source