Python中对象的__hash __()和__eq __()的源代码是什么?

时间:2016-02-29 20:49:00

标签: python python-internals

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

请参阅此答案(Finding the source code for built-in Python functions?),我在cpython中搜索对象定义。

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

2 个答案:

答案 0 :(得分:3)

__eq__object的默认实施继承自基础PyTypeObject PyBaseObject_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "object", /* tp_name */ … (hashfunc)_Py_HashPointer, /* tp_hash */ … object_richcompare, /* tp_richcompare */ … }; 类型。您可以在Objects/object.c中找到其类型定义:

tp_hash

对于散列函数(_Py_HashPointer),使用引用的默认散列函数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; } 。它在http://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest/createObject

中定义
__eq__

这基本上使用指针地址作为哈希的基础。

调用tp_richcompare时,Python所做的是执行丰富的比较(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; } )。这包括平等和非平等检查以及比较大或小的比较。默认实现使用typeobject.c,这需要引用相等:

{{1}}

答案 1 :(得分:2)

由于某种原因,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.__hash__,而Python/pyhash.c的{​​{1}}实施PyTypeObject PyBaseObject_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "object", /* tp_name */ ... 0, /* tp_compare */ ... (hashfunc)_Py_HashPointer, /* tp_hash */ ... 0, /* tp_richcompare */

object_richcompare中:

object.__eq__

==根本不存在,因此_Py_HashPointer最终会回到_Py_HashPointer中的指针比较。 table <- " trt rep ss d1 d4 d5 d6 d7 1 1 1 0 0 0 0 0 1 1 2 0 0 0 0 0 1 1 3 0 0 1 2 2 1 2 1 0 0 1 3 6 1 2 2 0 1 1 2 4 1 2 3 0 0 0 1 1 1 3 1 0 0 0 0 0 1 3 2 0 0 0 0 0 1 3 3 0 1 1 1 1 2 1 1 0 0 0 0 0 2 1 2 0 0 0 1 1 2 1 3 0 0 0 1 1 2 2 1 0 0 0 0 0 2 2 2 0 0 0 0 0 2 2 3 0 0 0 0 1 2 3 1 0 0 0 0 0 2 3 2 0 0 0 1 3 2 3 3 . . . . . " d <- read.table(text=table, header = TRUE, check.names = F, na.strings = ".") 仍然存在,但它位于Python 2.7