问题
object is a base for all new style classes. Where can I find the source code of object? I'd like to have a look how the function __hash__() and __eq__() are defined.
Refer to this answer (Finding the source code for built-in Python functions?), I search the object definition in cpython.
There is not __hash__() and __eq__() definiton in https://hg.python.org/cpython/file/tip/Objects/object.c.
回答1:
The default implementations for __hash__ and __eq__ are inherited from the base object type. You can find its type definition in typeobject.c:
PyTypeObject PyBaseObject_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"object", /* tp_name */
…
(hashfunc)_Py_HashPointer, /* tp_hash */
…
object_richcompare, /* tp_richcompare */
…
};
For the hash function (tp_hash), the default hash function for references is used, _Py_HashPointer. It is defined in 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;
}
This basically uses the pointer address as a base for the hash.
When __eq__ is called, what Python does under the hood is perform a rich comparison (tp_richcompare). This includes both equality and non-equality check as well as comparisons like greater or lower than. The default implementation is using object_richcompare which requires a reference equality:
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;
}
回答2:
The object implementation is actually in Objects/typeobject.c, for some reason. Looking in that file, you can see from the PyBaseObject_Type definition:
PyTypeObject PyBaseObject_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"object", /* tp_name */
...
(hashfunc)_Py_HashPointer, /* tp_hash */
...
object_richcompare, /* tp_richcompare */
that object.__eq__ is implemented in object_richcompare, and object.__hash__ is implemented in _Py_HashPointer from Python/pyhash.c.
In Python 2.7:
PyTypeObject PyBaseObject_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"object", /* tp_name */
...
0, /* tp_compare */
...
(hashfunc)_Py_HashPointer, /* tp_hash */
...
0, /* tp_richcompare */
object.__eq__ simply doesn't exist, so == ultimately falls back on a pointer comparison in default_3way_compare. _Py_HashPointer still exists, but it's in Objects/object.c
来源:https://stackoverflow.com/questions/35709339/what-is-the-source-code-of-hash-and-eq-of-object-in-python