Identidad booleana == Verdadero vs es verdadero

Es una convención estándar usar if foo is None lugar de if foo == None para probar si un valor es específicamente None .

Si desea determinar si un valor es exactamente True (no solo un valor verdadero), ¿hay alguna razón para usar if foo == True lugar de if foo is True ? ¿Esto varía entre implementaciones como CPython (2.xy 3.x), Jython, PyPy, etc.?

Ejemplo: say True se usa como un valor singleton que desea diferenciar del valor 'bar' , o cualquier otro valor de tipo true:

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

¿Hay un caso en el que usar if foo is True daría resultados diferentes if foo == True ?

NOTA: Soy consciente de los booleanos de Python: si x :, vs si x == True, vs si x es True . Sin embargo, solo trata if foo , if foo == True , o if foo is True deberían usarse para determinar si foo tiene un valor verdadero.


ACTUALIZACIÓN: Según PEP 285 § Especificación:

Los valores False y True serán singletons, como None.

Si desea determinar si un valor es exactamente verdadero (no solo un valor verdadero), ¿hay alguna razón para usar si foo == True en lugar de si foo es True?

Si desea asegurarse de que foo realmente un valor booleano y de valor True , utilice el operador is .

De lo contrario, si el tipo de foo implementa su propio __eq__() que devuelve un valor true-ish cuando se compara con True , podría terminar con un resultado inesperado.

Como regla general, siempre debe usar is con las constantes integradas True , False y None .

¿Esto varía entre implementaciones como CPython (2.xy 3.x), Jython, PyPy, etc.?

En teoría, será más rápido que == ya que esta última debe respetar las implementaciones personalizadas de __eq__ tipos, mientras is puede comparar directamente las identidades de los objetos (por ejemplo, las direcciones de memoria).

No sé el código fuente de las diversas implementaciones de Python de memoria, pero supongo que la mayoría de ellas pueden optimizar eso mediante el uso de algunas señales internas para la existencia de métodos mágicos, así que sospecho que no notará la diferencia de velocidad. en la práctica.

Nunca usar is True en combinación con numpy (y derivados como 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 

Esto fue inesperado para mí como:

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

Supongo que la explicación está dada por:

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

¿hay alguna razón para usar si foo == True en lugar de si foo es True? ”

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

Tenga en cuenta que bool es una subclase de int , y que True tiene el valor entero 1 . Para responder a su pregunta, si desea verificar que alguna variable “es exactamente verdadera”, debe usar el operador de identidad. Pero eso realmente no es pythonic … ¿Puedo preguntarle cuál es su caso de uso real? IOW: ¿por qué quiere hacer una diferencia entre True , 1 o cualquier valor de “verdad”?

La mayoría de las veces, no debes preocuparte por un detalle como este. O bien, ya sabe que foo es un booleano (y, por lo tanto, puede usar if foo ), o sabe que foo es otra cosa (en cuyo caso no es necesario realizar una prueba). Si no conoce los tipos de sus variables, puede refactorizar su código.

Pero si realmente necesita estar seguro de que es exactamente True y nada más, su uso is . Usar == te dará 1 == True .

Aquí hay una prueba que le permite ver la diferencia entre las 3 formas de prueba de Verdadero:

 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' [] FFF [1] TFF 0 FFF 1 TTF 2 TFF 

Como puede ver, hay casos en los que todos ellos ofrecen resultados diferentes.

edit: re is True vs ==

Hay un caso, y es este:

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

Además, para singletons como valor de centinela, solo puede usar una clase

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

no desea utilizar if var == True: realmente desea if var:

Imagina que tienes una lista. no te importa si una lista es ” True ” o no, solo quieres saber si está vacía o no. asi que…

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

Echa un vistazo a esta publicación para ver lo que se evalúa como False : Evaluación de expresiones booleanas en Python