Почему хеш (Нет) изменяется на разных платформах и в разных вызовах?
Я столкнулся с действительно странным поведением с хэш-функцией на Python. Когда я запускаю следующую команду в Mac OS (10.10), я получаю разные значения от разных вызовов.
$ python -c "print hash(None)"
-9223372036579216774
$ python -c "print hash(None)"
-9223372036582852230
С другой стороны, когда я запускаю то же самое на Ubuntu 14.04, я получаю:
$ python -c "print hash(None)"
596615
$ python -c "print hash(None)"
596615
Для меня это похоже, в OS X, python использует адрес памяти как-то, а Ubuntu - нет. Из этого я вижу, что хэш-функция, вероятно, зависит от реализации. Но разве это не должно основываться только на "ценности" Ничего? Что представляют собой эти цифры? Почему он ведет себя по-разному даже на одной и той же версии python, но на разных ОС?
Ответы
Ответ 1
None.__hash__
коррелирует с хэш-функцией _Py_HashPointer
. Поэтому в основном указатель объекта используется как хэш. Для None
, имеющего один сингл, это безопасно использовать, но не детерминировать. Для того, чтобы указатель, присвоенный подходящему целочисленному типу p
, значение хэша вычисляется следующим образом:
(p >> 4) | (p << (8 * SIZEOF_VOID_P - 4))
Ссылаясь на это, в исходном коде говорится:
нижние 3 или 4 бита, вероятно, равны 0; поверните y на 4, чтобы избежать чрезмерных столкновений хэша для dicts и наборов