Как делает Python (2.6.4, конкретно) определяют членство в списке в целом? Я запустил некоторые тесты для наблюдения то, что это делает:
def main():
obj = fancy_obj(arg='C:\\')
needle = (50, obj)
haystack = [(50, fancy_obj(arg='C:\\')), (1, obj,), needle]
print (1, fancy_obj(arg='C:\\'),) in haystack
print needle in haystack
if __name__ == '__main__':
main()
Который уступает:
False
True
Это говорит мне, что Python, вероятно, проверяет ссылки на объект, который имеет смысл. Действительно ли там что-то более категорично, я могу посмотреть на?
Из (An Unofficial) Python Reference Wiki:
Для типов list и tuple, x in y
истинно тогда и только тогда, когда существует индекс i такой, что x == y[i]
истинно.
Итак, в вашем примере, если класс fancy_obj
хранит значение arg
в переменной экземпляра и реализует метод __eq__
, который возвращает True, если два сравниваемых fancy_obj
имеют одинаковое значение для arg
, то (1, fancy_obj(arg='C: \\\'),) в haystack
было бы True.
Соответствующая страница справочника по стандартной библиотеке: Встроенные типы, а именно 5.6 Типы последовательностей
Вот код из Python SVN:
static int
list_contains(PyListObject *a, PyObject *el)
{
Py_ssize_t i;
int cmp;
for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i),
Py_EQ);
return cmp;
}
так что в основном он использует ==
с объектом и каждым объектом в списке.
Python использует (эквивалент) оператора ==
. Если класс fancy_obj
не определяет __eq__
(или старый добрый __cmp__
, который все еще поддерживается для обратной совместимости), то равенство, ==
, "возвращается" к тождеству, is
, и, похоже, именно это происходит здесь.
Соответствующие документы находятся здесь, цитирую:
x in s
True, если элемент s равен x, иначе False
и "равно" означает, что ==
истинно.