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

Python допускает значения хеш-функции только для неизменяемых объектов. Например,

hash((1,2,3))

работает, но

hash([1,2,3])

поднимает TypeError: unhashable type: 'list', Смотрите документацию по Python. Однако, когда я оборачиваю класс C++ в Boost.Python через обычный boost::python::class_<> Функция, каждый сгенерированный класс Python имеет хеш-функцию по умолчанию, где значение хеш-функции связано с расположением объекта в памяти. (В моей 64-битной ОС значение хеша - это место, разделенное на 8.)

Когда я предоставляю класс Python, члены которого могут быть изменены (любая изменяемая структура данных, так что это очень распространенная ситуация!), Я не хочу использовать хэш-функцию по умолчанию, но хочу вызвать hash() поднять же TypeError как пользователи получают для Python собственные изменяемые типы данных. В частности, пользователи не должны иметь возможность случайно использовать изменяемые объекты в качестве ключей словаря. Как я могу добиться этого в коде C++?

2 ответа

Решение

Я узнал, как это происходит:

boost::python::class_<MyClass>("MyClass")
  .setattr("__hash__", boost::python::object());

boost::python::object который инициализируется без аргументов, соответствует None, Процедура отключения генерации хеша в чистом API Python C немного сложнее, как описано в документации по Python. Однако приведенный выше фрагмент кода, очевидно, выполняет свою работу в boost::python.

О sidenote: Поведение Boost.Python отражает поведение классов по умолчанию в Python, где объекты в основном можно хэшировать с идентификатором объекта (производным от id(x)):

>>> hash(object())
8795488122377
>>> class MyClass(object): pass
... 
>>> hash(MyClass)
878579
>>> hash(MyClass())
8795488082665
>>> 
Другие вопросы по тегам