Python中对象的__hash__()和__eq__()的源代码是什么?

What is the source code of __hash__() and __eq__() of object in Python?

object 是所有新样式 类 的基础。哪里可以找到object的源代码?我想看看函数 __hash__()__eq__() 是如何定义的。

参考这个回答(Finding the source code for built-in Python functions?), I search the object definition in cpython

https://hg.python.org/cpython/file/tip/Objects/object.c中没有__hash__()__eq__()定义。

由于某种原因,object 实现实际上在 Objects/typeobject.c 中。查看该文件,您可以从 PyBaseObject_Type definition:

中看到
PyTypeObject PyBaseObject_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "object",                                   /* tp_name */
    ...
    (hashfunc)_Py_HashPointer,                  /* tp_hash */
    ...
    object_richcompare,                         /* tp_richcompare */

object.__eq__object_richcompare, and object.__hash__ is implemented in _Py_HashPointer 中从 Python/pyhash.c 实现。

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__ 根本不存在,所以 == 最终求助于 default_3way_compare. _Py_HashPointer still exists, but it's in Objects/object.c

中的指针比较

__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;
}