Тангенциальный ответ, но ваш вопрос и мои тесты вызвали у меня любопытство. Если вы игнорируете оператор set, который является источником вашей проблемы __hash__
, то ваш вопрос по-прежнему интересен.
Благодаря помощи, которую я получил по этому такому вопросу , я смог отследить оператор in через исходный код до его корня. Внизу я нашел функцию PyObject_RichCompareBool, которая действительно проверяет идентичность (см. Комментарий о «Быстрый результат») перед проверкой на равенство.
Так что, если я не пойму неправильно, как все работает, технический ответ на ваш вопрос - сначала идентичность, а затем равенство, через сам тест на равенство. Просто повторюсь, это не источник поведения, которое вы видели, а просто технический ответ на ваш вопрос.
Если я неправильно понял источник, кто-нибудь, пожалуйста, поправьте меня.
int
PyObject_RichCompareBool(PyObject *v, PyObject *w, int op)
{
PyObject *res;
int ok;
/* Quick result when objects are the same.
Guarantees that identity implies equality. */
if (v == w) {
if (op == Py_EQ)
return 1;
else if (op == Py_NE)
return 0;
}
res = PyObject_RichCompare(v, w, op);
if (res == NULL)
return -1;
if (PyBool_Check(res))
ok = (res == Py_True);
else
ok = PyObject_IsTrue(res);
Py_DECREF(res);
return ok;
}