Identidad booleana = = True vs is True


Es una convención estándar usar if foo is None en 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 similar al verdadero), ¿hay alguna razón para usar if foo == True en lugar de if foo is True? ¿Varía esto entre implementaciones como CPython (2.x y 3.x), Jython, PyPy, etc.?

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

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

¿Hay algún caso en el que usar if foo is True daría resultados diferentes de if foo == True?

NOTA: Conozco los booleanos de Python - if x:, vs if x == True, vs if x is True. Sin embargo, solo aborda si if foo, if foo == True, o if foo is True generalmente se debe usar para determinar si foo tiene un valor similar a true.


ACTUALIZACIÓN: De acuerdo con PEP 285 § Especificación:

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

Author: Community, 2014-12-03

6 answers

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

Si desea asegurarse de que foo es realmente un 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, usted siempre debe usar is con las constantes integradas True, False y None.

¿Varía esto entre implementaciones como CPython (2.x y 3.x), Jython, PyPy, etc.?

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

No conozco el código fuente de las diversas implementaciones de Python de memoria, pero supongamos que la mayoría de ellos pueden optimizar eso mediante el uso de algunas banderas internas para la existencia de métodos mágicos, por lo que sospecho que no notará la diferencia de velocidad en la práctica.

 23
Author: Ferdinand Beyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-06 21:18:30

Nunca use 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 es dada por:

In[6]: type(a)
Out[6]: numpy.bool_
 16
Author: kadee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-10 09:10:17

¿Hay alguna razón para usar if foo == True en lugar de if foo is 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 is. Pero eso realmente no es pitónico... ¿Puedo preguntar cuál es su caso de uso real-IOW: ¿por qué desea hacer una diferencia entre True, 1 o cualquier valor de' verdad' ?

 8
Author: bruno desthuilliers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-26 14:51:11

La mayoría de las veces, no deberías preocuparte por un detalle como este. O ya sabes que foo es un booleano (y por lo tanto puedes usar if foo), o sabes que foo es otra cosa (en cuyo caso no hay necesidad de probar). Si no conoce los tipos de sus variables, es posible que desee refactorizar su código.

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

 1
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-03 16:33:31

Aquí hay una prueba que le permite ver la diferencia entre las 3 formas de prueba 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

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

 0
Author: Mark Ransom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-03 16:33:55

edit: re is True vs ==

Hay un caso, y es este:{[12]]}

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

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

También, para singletons como un valor centinela, solo puede usar una clase

class SentinelTime(object): pass

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

No quieres usar if var == True:, realmente quieres 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. tan...

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

Echa un vistazo a este post para lo que evalúa a False: Evaluación de expresiones booleanas en Python

 0
Author: acushner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:25