Comparación de Python None: ¿debo usar "is" o ==?


213

Mi editor me advierte cuando comparo my_var == None, pero no me avisa cuando lo uso my_var is None.

Hice una prueba en el shell de Python y determiné que ambas son una sintaxis válida, pero mi editor parece estar diciendo que my_var is Nonees preferible.

¿Es este el caso, y si es así, por qué?


77
PEP 8 dice en alguna parte que debe comparar con los singletons usando is- python.org/dev/peps/pep-0008/#programming-recommendations
Volatility

2
Ese póster habla sobre Python 3, y mi pregunta es sobre Python 2.x. No estoy seguro de si esta es una diferencia lo suficientemente grande como para garantizar que ambos permanezcan, pero edité la pregunta para incluirla por si acaso.
Clay Wardell

2
No creo que esta pregunta sea realmente un duplicado. El otro era sobre == vs es en general, este es sobre Ninguno en particular.
IJ Kennedy

Respuestas:


254

Resumen:

Úselo iscuando desee verificar la identidad de un objeto (por ejemplo, verificar si vares así None). Úselo ==cuando desee verificar la igualdad (por ejemplo, es varigual a3 ?).

Explicación:

Puede tener clases personalizadas donde my_var == NonevolveráTrue

p.ej:

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

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

iscomprueba la identidad del objeto . Solo hay 1 objeto None, así que cuando lo haces my_var is None, estás verificando si realmente son el mismo objeto (no solo equivalente objetos )

En otras palabras, ==es una verificación de equivalencia (que se define de un objeto a otro) mientras que isverifica la identidad del objeto:

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

22
¿Cuándo is Nonedifiere de == None?
Blender

11
@Blender En el caso mencionado. __eq__se puede definir de cualquier manera, pero el comportamiento de isno se puede cambiar tan fácilmente.
Lev Levitsky

55
@LevLevitsky: Uno de los usos de ejemplo de Mython fue "extender los protocolos para que cualquier operador pueda sobrecargarse, incluso is". Después de un comentario en las listas, cambió eso a "... incluso is(pero solo si estás loco)".
abarnert

1
+1, pero sería aún mejor si esta respuesta incluyera la referencia de PEP 8 que hacen los demás (además de explicar por qué la decisión detrás de PEP 8 tiene sentido, que ya lo hace).
abarnert el

3
@abarnert: ni siquiera sabía que PEP 8 hacía una recomendación aquí. El punto es que son operadores diferentes que hacen cosas diferentes. Puede haber casos en los que object == Nonerealmente sea el idioma correcto (aunque no puedo pensar en ninguno fuera de mi cabeza). Solo necesitas saber lo que estás haciendo.
mgilson

127

isgeneralmente se prefiere cuando se comparan objetos arbitrarios con singletons como Noneporque es más rápido y más predecible. issiempre se compara por identidad de objeto, mientras que lo ==que hará dependerá del tipo exacto de los operandos e incluso de su orden.

Esta recomendación es respaldada por PEP 8 , que establece explícitamente que "las comparaciones con singletons como None siempre deben hacerse con iso is not, nunca, los operadores de igualdad".


66
Gracias por publicar esto; la respuesta aceptada hace algunos puntos interesantes, pero la suya responde a la pregunta mucho más directamente.
Luke Davis el

Parece extraño confiar en lo que es esencialmente un detalle de implementación. ¿Por qué debería importarme cuántas instancias de NoneType hay?
BallpointBen

@BallpointBen Debido a que no es un detalle de implementación, solo hay un Noneobjeto debajo de la constante global None. En todo caso, NoneTypees un detalle de implementación porque el Nonesingleton debe tener algún tipo. (El hecho de que no pueda crear instancias de este tipo es una buena indicación de que su única instancia está destinada a ser un singleton.)
user4815162342

@BallpointBen Creo que el punto clave es que Python posee un fuerte concepto de identidad de objeto. Si desea comprobar si un objeto se compara igual a None, utilice todos los medios obj == None. Si desea verificar si un objeto es None , use obj is None. El punto de la recomendación de PEP 8 (y de esta respuesta) es que la mayoría de las personas quieren este último cuando quieren verificar Ninguno, y también resulta ser más rápido y más claro.
user4815162342

NoneTambién es diferente de los objetos en caché como 0y otros enteros pequeños, donde el almacenamiento en caché es realmente un detalle de implementación. La diferencia es que un número entero tiene un valor intrínseco que le da sus propiedades y puede calcularse. Por otro lado, Noneno tiene ningún tipo de estado, es solo su identidad lo que importa y lo hace especial.
user4815162342

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.