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.)
isEs 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 la isoperación.
Utiliza is(y is not) para los singletons, por ejemplo None, donde no le importan los objetos que podrían pretender ser Noneo donde desea protegerse contra los objetos que se rompen cuando se los compara None.
Nonetiene 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á si otherresulta ser None.
ises como el de Java ==. Python ==es como el de Java .equals(). Por supuesto, esto solo ayuda si conoces Java.
ises como ===(muy igual), y por el contrario is notes como !==(no exactamente igual).
is notun solo operador o simplemente está negando el resultado de ser isinterno not 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".
Identidad del objeto : cuando crea un objeto, puede asignarlo a una variable. Entonces también puede asignarlo a otra variable. Y otro.
>>> button = Button()
>>> cancel = button
>>> close = button
>>> dismiss = button
>>> print(cancel is close)
True
En este caso, cancel, close, y dismisstodos se refieren al mismo objeto en la memoria. Solo creó un Buttonobjeto, y las tres variables se refieren a este objeto. Decimos eso cancel, closey dismisstodos 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 diciendo if a.__eq__(b):. Esto le permite definir un __eq__método apara que pueda usar su propia lógica de comparación.
Justificación: Dos objetos tienen exactamente los mismos datos, pero no son idénticos. (No son el mismo objeto en la memoria). Ejemplo: cadenas
>>> greeting = "It's a beautiful day in the neighbourhood."
>>> a = unicode(greeting)
>>> b = unicode(greeting)
>>> a is b
False
>>> a == b
True
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, ay b. 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.
class unicode(object):
# ...
def __eq__(self, other):
if len(self) != len(other):
return False
for i, j in zip(self, other):
if i != j:
return False
return True
Nota: __eq__on unicodedefinitivamente 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
>>> import datetime
>>> a = Monitor()
>>> a.make = "Dell"
>>> a.model = "E770s"
>>> a.owner = "Bob Jones"
>>> a.warranty_expiration = datetime.date(2030, 12, 31)
>>> b = Monitor()
>>> b.make = "Dell"
>>> b.model = "E770s"
>>> b.owner = "Sam Johnson"
>>> b.warranty_expiration = datetime.date(2005, 8, 22)
>>> a is b
False
>>> a == b
True
Aquí tengo dos monitores Dell ay b. 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.
class Monitor(object):
# ...
def __eq__(self, other):
return self.make == other.make and self.model == other.model
Al comparar con None, siempre use is 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 es None.
¿No lo implementaste __eq__? Entonces, Python probablemente encontrará el __eq__método objecty 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á !=.
Considera lo siguiente:
class Bad(object):
def __eq__(self, other):
return True
c = Bad()
c is None # False, equivalent to id(c) == id(None)
c == None # True, equivalent to c.__eq__(None)
Nonees 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__().
None, pero un comportamiento incorrecto Nonepodrí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.
>>> () es () Cierto >>> 1 es 1 Cierto >>> (1,) == (1,) Cierto >>> (1,) es (1,) Falso >>> a = (1,) >>> b = a >>> a es b Cierto
Algunos objetos son singletons y, por lo tanto, iscon ellos es equivalente a ==. La mayoría no lo son.
()y 1no 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.