En un comentario sobre esta pregunta , vi una declaración que recomendaba usar
result is not None
vs
result != None
Me preguntaba cuál es la diferencia y por qué uno podría recomendarse sobre el otro.
En un comentario sobre esta pregunta , vi una declaración que recomendaba usar
result is not None
vs
result != None
Me preguntaba cuál es la diferencia y por qué uno podría recomendarse sobre el otro.
Respuestas:
==
Es una prueba de igualdad . Se comprueba si el lado derecho y el lado izquierdo son iguales objetos (según su__eq__
o__cmp__
métodos.)is
Es una prueba de identidad . Comprueba si el lado derecho y el lado izquierdo son el mismo objeto. No se realizan llamadas a métodos, los objetos no pueden influir en lais
operación.Utiliza
is
(yis not
) para los singletons, por ejemploNone
, donde no le importan los objetos que podrían pretender serNone
o donde desea protegerse contra los objetos que se rompen cuando se los comparaNone
.fuente
None
tiene pocos métodos y casi no tiene atributos. Si su__eq__
prueba esperaba un método o atributo, podría romperse.def __eq__( self, other ): return self.size == other.size
. Por ejemplo, se romperá siother
resulta serNone
.is
es como el de Java==
. Python==
es como el de Java.equals()
. Por supuesto, esto solo ayuda si conoces Java.is
es como===
(muy igual), y por el contrariois not
es como!==
(no exactamente igual).is not
un solo operador o simplemente está negando el resultado de seris
internonot foo is bar
?Primero, déjenme repasar algunos términos. Si solo desea que su pregunta sea respondida, desplácese hacia abajo hasta "Responder su pregunta".
Definiciones
Identidad del objeto : cuando crea un objeto, puede asignarlo a una variable. Entonces también puede asignarlo a otra variable. Y otro.
En este caso,
cancel
,close
, ydismiss
todos se refieren al mismo objeto en la memoria. Solo creó unButton
objeto, y las tres variables se refieren a este objeto. Decimos esocancel
,close
ydismiss
todos se refieren a objetos idénticos ; es decir, se refieren a un solo objeto.Igualdad de objeto : cuando compara dos objetos, generalmente no le importa que se refiera exactamente al mismo objeto en la memoria. Con la igualdad de objetos, puede definir sus propias reglas sobre cómo se comparan dos objetos. Cuando escribes
if a == b:
, esencialmente estás diciendoif a.__eq__(b):
. Esto le permite definir un__eq__
métodoa
para que pueda usar su propia lógica de comparación.Justificación de las comparaciones de igualdad
Justificación: Dos objetos tienen exactamente los mismos datos, pero no son idénticos. (No son el mismo objeto en la memoria). Ejemplo: cadenas
Nota: Aquí uso cadenas Unicode porque Python es lo suficientemente inteligente como para reutilizar cadenas normales sin crear nuevas en la memoria.
Aquí, tengo dos cadenas unicode,
a
yb
. Tienen exactamente el mismo contenido, pero no son el mismo objeto en la memoria. Sin embargo, cuando los comparamos, queremos que se comparen igual. Lo que sucede aquí es que el objeto Unicode ha implementado el__eq__
método.Nota:
__eq__
onunicode
definitivamente se implementa de manera más eficiente que esto.Justificación: Dos objetos tienen datos diferentes, pero se consideran el mismo objeto si algunos datos clave son los mismos. Ejemplo: la mayoría de los tipos de datos del modelo
Aquí tengo dos monitores Dell
a
yb
. Tienen la misma marca y modelo. Sin embargo, no tienen los mismos datos ni son el mismo objeto en la memoria. Sin embargo, cuando los comparamos, queremos que se comparen igual. Lo que sucede aquí es que el objeto Monitor implementó el__eq__
método.Respondiendo tu pregunta
Al comparar con
None
, siempre useis not
. Ninguno es un singleton en Python; solo hay una instancia de este en la memoria.Al comparar la identidad , esto se puede realizar muy rápidamente. Python comprueba si el objeto al que se refiere tiene la misma dirección de memoria que el objeto Ninguno global: una comparación muy, muy rápida de dos números.
Al comparar la igualdad , Python tiene que buscar si su objeto tiene un
__eq__
método. Si no lo hace, examina cada superclase buscando un__eq__
método. Si encuentra uno, Python lo llama. Esto es especialmente malo si el__eq__
método es lento y no regresa de inmediato cuando se da cuenta de que el otro objeto lo esNone
.¿No lo implementaste
__eq__
? Entonces, Python probablemente encontrará el__eq__
métodoobject
y lo usará en su lugar, que de todos modos solo verifica la identidad del objeto.Al comparar la mayoría de las otras cosas en Python, lo usará
!=
.fuente
Considera lo siguiente:
fuente
None
es un singleton, por lo tanto, la comparación de identidad siempre funcionará, mientras que un objeto puede falsificar la comparación de igualdad a través de.__eq__()
.fuente
None
, pero un comportamiento incorrectoNone
podría ocurrir como un efecto secundario de la implementación de la igualdad contra otros tipos. No son tanto las implicaciones de seguridad como las implicaciones de corrección.Algunos objetos son singletons y, por lo tanto,
is
con ellos es equivalente a==
. La mayoría no lo son.fuente
()
y1
no son inherentemente solteros.-NSMALLNEGINTS <= n <= NSMALLPOSINTS
) y las tuplas vacías son singletons. De hecho, no está documentado ni garantizado, pero es poco probable que cambie.