<p>这不是一个明确的答案,但这里有一些轨道来理解这种行为。</p>
<p>我这里指的是1.6.1版本的numpy代码。</p>
<p>根据<code>numpy.ndarray</code>对象实现(看,<code>numpy/core/src/multiarray/arrayobject.c</code>),将<code>hash</code>方法设置为<code>NULL</code>。</p>
<pre><code>NPY_NO_EXPORT PyTypeObject PyArray_Type = {
#if defined(NPY_PY3K)
PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
#endif
"numpy.ndarray", /* tp_name */
sizeof(PyArrayObject), /* tp_basicsize */
&array_as_mapping, /* tp_as_mapping */
(hashfunc)0, /* tp_hash */
</code></pre>
<p>此<code>tp_hash</code>属性似乎在<code>numpy/core/src/multiarray/multiarraymodule.c</code>中被重写。请参见<code>DUAL_INHERIT</code>、<code>DUAL_INHERIT2</code>和<code>initmultiarray</code>函数,其中<code>tp_hash</code>属性被修改。</p>
<p>例如:
pyarraydesrc_Type.tp_hash=PyArray_DescrHash</p>
<p>根据<code>hashdescr.c</code>,hash实现如下:</p>
<pre><code>* How does this work ? The hash is computed from a list which contains all the
* information specific to a type. The hard work is to build the list
* (_array_descr_walk). The list is built as follows:
* * If the dtype is builtin (no fields, no subarray), then the list
* contains 6 items which uniquely define one dtype (_array_descr_builtin)
* * If the dtype is a compound array, one walk on each field. For each
* field, we append title, names, offset to the final list used for
* hashing, and then append the list recursively built for each
* corresponding dtype (_array_descr_walk_fields)
* * If the dtype is a subarray, one adds the shape tuple to the list, and
* then append the list recursively built for each corresponding type
* (_array_descr_walk_subarray)
</code></pre>