令我非常沮丧的是,我设法在python中创建一个对象列表,以便以下操作失败:
if foo in lst:
lst.index(foo) # ValueError: <foo> is not in list
我向你保证,这里没有任何诡计:
foo
是一个自定义__hash__
和__eq__
的对象,未在其他地方修改lst
是一个没有诅咒的标准python []
答案 0 :(得分:4)
obj in listobject
(或listobject.__contains__(obj)
)与listobject.index()
之间的唯一区别是比较倒置。
list_contains
:
for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i),
Py_EQ);
而listindex
会这样做;
for (i = start; i < stop && i < Py_SIZE(self); i++) {
int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
其中el
和v
是查找对象,PyList_GET_ITEM(a, i)
和self->ob_item[i]
是列表中包含的对象。
因此lst.index()
会引发ValueError
个异常,因为所有other.__eq__(foo)
次调用都会返回False
,而且foo.__eq__(other)
永远不会被查阅。 foo in lst
有效,因为foo.__eq__(other)
确实会为至少一个值返回True
。
您尚未向我们提供示例列表和__eq__
实施,以验证 __eq__
为False
次调用返回other.__eq__(foo)
的原因