Хеш Python не детерминирован с объектами sympy


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

import sympy as sym
x = sym.symbols('x')
print(hash(x))

Есть ли способ детерминистски хешированные символические выражения?

2 2

2 ответа:

Вы столкнулись с функцией безопасности, известной как хэш-рандомизация.

$ cat hash_test.py 
import sympy as sym
x = sym.symbols('x')
print(hash(x))

Несколько запусков с этим простым примером:

$ python hash_test.py 
6842375726913792912
$ python hash_test.py 
5041915772945005780
$ python hash_test.py 
-3461975266180802906

Запуск без хэш-рандомизации для получения тех же результатов:

$ PYTHONHASHSEED=0 python hash_test.py 
-2285490307665029553
$ PYTHONHASHSEED=0 python hash_test.py 
-2285490307665029553
$ PYTHONHASHSEED=0 python hash_test.py 
-2285490307665029553

Отсюда: http://docs.sympy.org/latest/python-comparisons.html https://docs.python.org/dev/glossary.html#term-hashable

Объекты, являющиеся экземплярами пользовательских классов, хешируются с помощью по умолчанию. Все они сравниваются неравноценно (кроме самих себя), и их хэш-значение выводится из их id().

def __hash__(self):
    return id(self)

Что, как я полагаю, является причиной того, что у вас есть другой хэш, так как экземпляры имеют другой идентификатор.

Я надеюсь, что вы можете получить сравнение, которое вам нужно, из первого документа, который я опубликовал.