python - strings - ¿Los objetos con la misma identificación siempre son iguales al compararlos con==?
python=> (3)
El papel es correcto. Considera lo siguiente.
class WeirdEquals:
def __eq__(self, other):
return False
w = WeirdEquals()
print("id(w) == id(w)", id(w) == id(w))
print("w == w", w == w)
La salida es esta:
id(w) == id(w) True
w == w False
Si tengo dos objetos o1 y o2, y sabemos que
id(o1) == id(o2)
devuelve verdadero
Entonces, ¿se sigue que
o1 == o2
¿O no es este siempre el caso? El documento en el que estoy trabajando dice que este no es el caso, ¡pero en mi opinión debería ser cierto!
No siempre:
>>> nan = float(''nan'')
>>> nan is nan
True
o formulado de la misma manera que en la pregunta:
>>> id(nan) == id(nan)
True
pero
>>> nan == nan
False
NaN
es una cosa extraña.
Por definición, no es igual ni menor ni mayor que sí mismo.
Pero es el mismo objeto.
Más detalles por qué todas las comparaciones tienen que devolver
False
en
esta pregunta SO
.
id(o1) == id(o2)
no implica
o1 == o2
.
Echemos un vistazo a este
Troll
que anula
__eq__
para devolver siempre
False
.
>>> class Troll(object):
... def __eq__(self, other):
... return False
...
>>> a = Troll()
>>> b = a
>>> id(a) == id(b)
True
>>> a == b
False
Dicho esto, debería haber
muy
pocos ejemplos en la biblioteca estándar donde los
__eq__
-objeto coincidan, pero
__eq__
puede devolver
False
todos modos, felicitaciones @ MarkMüller por encontrar un buen ejemplo.
Entonces, o los objetos son locos, muy especiales (como nan), o la concurrencia te muerde.
Considere este ejemplo extremo, donde
Foo
tiene un método
__eq__
más razonable (que ''olvida'' verificar los identificadores) y
f is f
siempre es
True
.
import threading
class Foo(object):
def __init__(self):
self.x = 1
def __eq__(self, other):
return isinstance(other, Foo) and self.x == other.x
f = Foo()
class MutateThread(threading.Thread):
def run(self):
while True:
f.x = 2
f.x = 1
class CheckThread(threading.Thread):
def run(self):
i = 1
while True:
if not (f == f):
print ''loop {0}: f != f''.format(i)
i += 1
MutateThread().start()
CheckThread().start()
Salida:
$ python eqtest.py
loop 520617: f != f
loop 1556675: f != f
loop 1714709: f != f
loop 2436222: f != f
loop 3210760: f != f
loop 3772996: f != f
loop 5610559: f != f
loop 6065230: f != f
loop 6287500: f != f
...