I have the following code, which is making me scratch my head -
class Element:
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
def eq(self, other):
print('comparing {} to {} ({})'.format(self.name,
other.name,
self.name == other.name))
return self.name == other.name
Element.__eq__ = eq
elements = [
Element('a'),
Element('b'),
Element('c'),
Element('d')
]
print('before {}'.format(elements))
elements.remove(elements[3])
print('after {}'.format(elements))
Which yields the following output -
before [a, b, c, d]
comparing a to d (False)
comparing b to d (False)
comparing c to d (False)
after [a, b, c]
Why isn't eq()
outputting comparing d to d (True)
?
The reason I'm monkey patching __eq__
instead of simply implementing it in my Element
class is because I'm testing how monkey patching works before I implement it with one of the libraries I'm using.
The fourth element is the exactly same object with the object the code is passing ( elements[3]
).
In other word,
>>> elements[3] is elements[3]
True
>>> elements[3] == elements[3]
True
So, no need to check the equality because they(?) are identical (same) one.
Equality check will happen if they are not identical. For example, __eq__
will be called if the code passes another object with the same value:
elements.remove(Element('d'))
Python's list.remove()
method first checks whether the both objects are identical otherwise falls back to regular comparison methods like __eq__
in this case. So, in this case as both objects are identical it is removed from the list.
listremove(PyListObject *self, PyObject *v)
{
Py_ssize_t i;
for (i = 0; i < Py_SIZE(self); i++) {
int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
...
Here PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid)
is being used for comparison, and from its docs:
If
o1
ando2
are the same object,PyObject_RichCompareBool()
will always return1
forPy_EQ
and0
forPy_NE
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.