Реализации по умолчанию для __hash__
и __eq__
унаследованы от базового типа object
. Вы можете найти его определение типа в typeobject.c
:
PyTypeObject PyBaseObject_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"object", /* tp_name */
…
(hashfunc)_Py_HashPointer, /* tp_hash */
…
object_richcompare, /* tp_richcompare */
…
};
Для хеш-функции (tp_hash
) используется хэш-функция по умолчанию для ссылок, _Py_HashPointer
. Он определен в pyhash.c
:
Py_hash_t
_Py_HashPointer(void *p)
{
Py_hash_t x;
size_t y = (size_t)p;
/* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
excessive hash collisions for dicts and sets */
y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4));
x = (Py_hash_t)y;
if (x == -1)
x = -2;
return x;
}
Это в основном использует адрес указателя в качестве основы для хэша.
Когда вызывается __eq__
, под капотом Python выполняет расширенное сравнение (tp_richcompare
). Это включает в себя как проверку на равенство, так и проверку на неравноправие, а также сравнения, такие как больше или меньше. Реализация по умолчанию использует object_richcompare
, что требует равенства ссылок :
static PyObject *
object_richcompare(PyObject *self, PyObject *other, int op)
{
PyObject *res;
switch (op) {
case Py_EQ:
/* Return NotImplemented instead of False, so if two
objects are compared, both get a chance at the
comparison. See issue #1393. */
res = (self == other) ? Py_True : Py_NotImplemented;
Py_INCREF(res);
break;
…
}
return res;
}
person
poke
schedule
29.02.2016
object.__eq__
илиobject.__hash__
. - person user2357112 supports Monica   schedule 01.03.2016