web-dev-qa-db-fra.com

Identité booléenne == True vs est True

Il est habituel d'utiliser if foo is None plutôt que if foo == None pour vérifier si une valeur est spécifiquement None.

Si vous voulez déterminer si une valeur correspond exactement à True (pas seulement une valeur vraie), y a-t-il une raison d'utiliser if foo == True plutôt que if foo is True? Cela varie-t-il entre les implémentations telles que CPython (2.x et 3.x), Jython, PyPy, etc.?

Exemple: say True est utilisé en tant que valeur singleton que vous souhaitez différencier de la valeur 'bar' ou de toute autre valeur de type true:

if foo is True: # vs foo == True
    ...
Elif foo == 'bar':
    ...

Existe-t-il un cas où l'utilisation de if foo is True donnerait des résultats différents de if foo == True?

NOTE: Je connais les booléens Python - si x :, vs si x == True, vs si x est True . Cependant, il indique uniquement si if foo, if foo == True ou if foo is True doit généralement être utilisé pour déterminer si foo a une valeur de type true.


MISE À JOUR: Selon PEP 285 § Spécification:

Les valeurs False et True seront des singletons, comme Aucune.

33
cpburnz

Si vous voulez déterminer si une valeur est exactement True (et pas seulement une valeur vraie), y a-t-il une raison à utiliser si foo == True plutôt que si foo est True?

Si vous voulez vous assurer que foo est vraiment un booléen et que vous avez la valeur True, utilisez l'opérateur is.

Sinon, si le type de foo implémente sa propre __eq__() qui renvoie une valeur true-ish lors de la comparaison avec True, vous risquez de vous retrouver avec un résultat inattendu.

En règle générale, vous devez toujours utiliser is avec les constantes intégrées True, False et None.

Cela varie-t-il entre les implémentations telles que CPython (2.x et 3.x), Jython, PyPy, etc.?

En théorie, is sera plus rapide que == car ce dernier doit respecter les implémentations __eq__ personnalisées des types, tandis que is peut directement comparer les identités d'objet (par exemple, les adresses de mémoire).

Je ne connais pas le code source des différentes implémentations Python par cœur, mais je suppose que la plupart d'entre elles peuvent optimiser cela en utilisant des indicateurs internes pour indiquer l'existence de méthodes magiques. Je suppose donc que vous ne remarquerez pas la différence de vitesse. en pratique.

27
Ferdinand Beyer

N'utilisez jamais is True en association avec numpy (et ses dérivés tels que les pandas):

In[1]: import numpy as np
In[2]: a = np.array([1, 2]).any()
In[4]: a is True
Out[4]: False
In[5]: a == True
Out[5]: True

C'était inattendu pour moi en tant que:

In[3]: a
Out[3]: True

Je suppose que l'explication est donnée par:

In[6]: type(a)
Out[6]: numpy.bool_
16
kadee

y a-t-il une raison à utiliser si foo == True plutôt que si foo est True? "

>>> d = True
>>> d is True
True
>>> d = 1
>>> d is True
False
>>> d == True
True
>>> d = 2
>>> d == True
False

Notez que bool est une sous-classe de int et que True a la valeur entière 1. Pour répondre à votre question, si vous voulez vérifier qu'une variable "est exactement vraie", vous devez utiliser l'opérateur d'identité is. Mais ce n'est vraiment pas Pythonic ... Puis-je vous demander quel est votre cas d'utilisation réel - IOW: pourquoi voulez-vous faire une différence entre True, 1 ou toute valeur de "vérité"?

10

La plupart du temps, vous ne devriez pas vous soucier d'un détail comme celui-ci. Soit vous savez déjà que foo est un booléen (et vous pouvez donc utiliser if foo), ou vous savez que foo est autre chose (dans ce cas, il n'est pas nécessaire de tester). Si vous ne connaissez pas les types de vos variables, vous voudrez peut-être refactoriser votre code.

Mais si vous avez vraiment besoin d’être sûr que c’est exactement True et rien d’autre, utilisez is. Utiliser == vous donnera 1 == True.

1
Kevin

Voici un test qui vous permet de voir la différence entre les 3 formes de test de True:

for test in ([], [1], 0, 1, 2):
    print repr(test), 'T' if test else 'F', 'T' if test == True else 'F', 'T' if test is True else 'F'

[] F F F
[1] T F F
0 F F F
1 T T F
2 T F F

Comme vous pouvez le constater, il arrive que tous produisent des résultats différents.

0
Mark Ransom

edit: re is True vs ==

il y a un cas, et c'est ceci:

In [24]: 1 is True
Out[24]: False

In [25]: 1 == True
Out[25]: True

aussi, pour les singletons comme valeur sentinelle, vous pouvez simplement utiliser une classe

class SentinelTime(object): pass

def f(snth):
    if snth is SentinelTime:
        print 'got em!'
f(SentinelTime)

vous ne voulez pas utiliser if var == True:, vous voulez vraiment if var:

imaginez que vous avez une liste. vous ne vous souciez pas de savoir si une liste est "True" ou pas, vous voulez juste savoir si elle est vide ou non. alors...

l = ['snth']
if l:
    print l

consultez ce post pour ce qui est évalué à False: Evaluation des expressions booléennes en Python

0
acushner