class A(object):
def __init__(self, value):
self.value = value
x = A(1)
y = A(2)
q = [x, y]
q.remove(y)
I want to remove from the list a specific object which was added before to it and to which I still have a reference. I do not want an equality test. I want an identity test. This code seems to work in both CPython and IronPython, but does the language guarantee this behavior or is it just a fluke?
The list.remove
method documentation is this: same as del s[s.index(x)]
, which implies that an equality test is performed.
So will an object be equal to itself if you don't override __cmp__
, __eq__
or __ne__
?
Yes. In your example q.remove(y)
would remove the first occurrence of an object which compares equal with y
. However, the way the class A
is defined, you shouldn't† ever have a variable compare equal with y
- with the exception of any other names which are also bound to the same y
instance.
The relevant section of the docs is here:
If no
__cmp__(), __eq__() or __ne__()
operation is defined, class instances are compared by object identity ("address").
So comparison for A
instances is by identity (implemented as memory address in CPython). No other object can have an identity equal to id(y)
within y
's lifetime, i.e. for as long as you hold a reference to y
(which you must, if you're going to remove it from a list!)
†Technically, it is still possible to have objects at other memory locations which are comparing equal - mock.ANY
is one such example. But these objects need to override their comparison operators to force the result.
In python, by default an object is always equal to itself (the only exception I can think of is float("nan")
. An object of a user-defined class will not be equal to any other object unless you define a comparison function.
See also http://docs.python.org/reference/expressions.html#notin
The answer is yes and no.
Consider the following example
>>> class A(object):
def __init__(self, value):
self.value = value
>>> x = A(1)
>>> y = A(2)
>>> z = A(3)
>>> w = A(3)
>>> q = [x, y,z]
>>> id(y) #Second element in the list and y has the same reference
46167248
>>> id(q[1]) #Second element in the list and y has the same reference
46167248
>>> q.remove(y) #So it just compares the id and removes it
>>> q
[<__main__.A object at 0x02C19AB0>, <__main__.A object at 0x02C19B50>]
>>> q.remove(w) #Fails because though z and w contain the same value yet they are different object
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
q.remove(w)
ValueError: list.remove(x): x not in list
It will remove from the list iff they are the same object. If they are different object with same value it won;t remove it.
来源:https://stackoverflow.com/questions/8588890/does-a-python-object-which-doesnt-override-comparison-operators-equals-itself