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