Является ли хэш python () постоянным? - PullRequest
0 голосов
/ 10 октября 2019

Гарантируется ли функция hash() в python всегда одинаковой для данного ввода, независимо от того, когда и где он введен? Пока что - только методом проб и ошибок - ответ вроде бы да, но было бы неплохо понять, как это работает. Например, в тесте:

$ python
>>> from ingest.tpr import *
>>> d=DailyPriceObj(date="2014-01-01") 
>>> hash(d)
5440882306090652359
>>> ^D
$ python
>>> from ingest.tpr import *
>>> d=DailyPriceObj(date="2014-01-01") 
>>> hash(d)
5440882306090652359

Ответы [ 3 ]

3 голосов
/ 10 октября 2019

Контракт для метода __hash__ требует, чтобы он был согласован в рамках данного запуска Python. нет гарантии того, что он будет согласован для различных запусков Python, и фактически для встроенных str, bytes -подобных типов и datetime.datetimeВ объектах (возможно, в других) хэш-память присваивается со значением для каждого прогона, так что он почти никогда не бывает одинаковым для одного и того же ввода в разных запусках Python.

1 голос
/ 11 октября 2019

A необходимое условие для хешируемости состоит в том, что для эквивалентных объектов это значение равно всегда одинаково ( внутри одного прогона интерпретатора ).

Конечно, ничто не мешает вам игнорировать это требование. Но если вы вдруг захотите сохранить свои объекты в словаре или наборе, то могут возникнуть проблемы.

Когда вы реализуете свой собственный класс, вы можете определить методы __eq__ и __hash__. Я использовал полиноминальную хеш-функцию для строк и хеш-функцию из универсального семейства хеш-функций.

Как правило, значения хеш-функции для конкретного объекта не должны изменяться от начала к началу интерпретатора. Но для многих типов данных это действительно так. Одна из причин этой реализации заключается в том, что сложнее найти и проверку на хеш.

Например:

Для числовых типов хеш числа x основан на уменьшении x по модулю простого P = 2**_PyHASH_BITS - 1. Он спроектирован так, что hash(x) == hash(y) всякий раз, когда x и y численно равны, даже если x и y имеют разные типы.

a = 123456789
hash(a) == 123456789
hash(a + b * (2 ** 61 - 1)) == 123456789
1 голос
/ 10 октября 2019

Нет, это зависит от процесса. Если вам нужен постоянный хеш, см. Постоянное хеширование строк в Python .

Усечение в зависимости от платформы, из документации __ hash __ :

hash () усекает значение, возвращаемое из пользовательского метода __hash __ () объекта, до размера Py_ssize_t. Обычно это 64 байта в 64-битных сборках и 4 байта в 32-битных сборках.

Соленые хэши из той же документации (ответ ShadowRanger):

Byпо умолчанию значения __hash __ () для объектов str, bytes и datetime «солят» с непредсказуемым случайным значением. Хотя они остаются постоянными в рамках отдельного процесса Python, они не предсказуемы между повторными вызовами Python. Это предназначено для обеспечения защиты от отказа в обслуживании, вызванного тщательно подобранными входами, которые используют наихудшую производительность при вставке dict, сложности O (n ^ 2). Подробнее см. http://www.ocert.org/advisories/ocert-2011-003.html.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...